示例#1
0
    def _validate_data_value(self, attrs):
        if self.instance and self.instance.pk:
            # ToDo , Should we allow PATCHing the object with different file?
            attrs['data_file'] = attrs.get('data_file',
                                           self.instance.data_file)
            attrs['data_type'] = attrs.get('data_type',
                                           self.instance.data_type)
            try:
                attrs['data_value']
            except KeyError:
                attrs['data_value'] = self.instance.data_value
                return attrs

        data_value = attrs.get('data_value')

        if attrs.get(
                'data_type') == 'media' and attrs.get('data_file') is None:
            message = {'data_value': t('Invalid url {}').format(data_value)}
            URLValidator(message=message)(data_value)

        if not data_value:
            raise serializers.ValidationError(
                {'data_value': t('This field is required.')})

        return attrs
示例#2
0
def delete_export(request, username, id_string, export_type):
    owner = get_object_or_404(User, username__iexact=username)
    xform = get_object_or_404(XForm, id_string__exact=id_string, user=owner)
    if not has_permission(xform, owner, request):
        return HttpResponseForbidden(t('Not shared.'))

    export_id = request.POST.get('export_id')

    # find the export entry in the db
    export = get_object_or_404(Export, id=export_id)

    export.delete()
    audit = {"xform": xform.id_string, "export_type": export.export_type}
    audit_log(
        Actions.EXPORT_DOWNLOADED, request.user, owner,
        t("Deleted %(export_type)s export '%(filename)s'"
          " on '%(id_string)s'.") % {
              'export_type': export.export_type.upper(),
              'filename': export.filename,
              'id_string': xform.id_string,
          }, audit, request)
    return HttpResponseRedirect(
        reverse(export_list,
                kwargs={
                    "username": username,
                    "id_string": id_string,
                    "export_type": export_type
                }))
示例#3
0
def publish_xlsform(request, user, existing_xform=None):
    """
    If `existing_xform` is specified, that form will be overwritten with the
    new XLSForm
    """
    if not request.user.has_perm(
        'can_add_xform',
        UserProfile.objects.get_or_create(user=user)[0]
    ):
        raise exceptions.PermissionDenied(
            detail=t("User %(user)s has no permission to add xforms to "
                     "account %(account)s" % {'user': request.user.username,
                                              'account': user.username}))
    if existing_xform and not request.user.has_perm(
            'change_xform', existing_xform):
        raise exceptions.PermissionDenied(
            detail=t("User %(user)s has no permission to change this "
                     "form." % {'user': request.user.username, })
        )

    def set_form():
        form = QuickConverterForm(request.POST, request.FILES)
        if existing_xform:
            return form.publish(user, existing_xform.id_string)
        else:
            return form.publish(user)

    return publish_form(set_form)
示例#4
0
    def retry(self, request, uid=None, *args, **kwargs):
        """
        Retries to send data to external service.
        :param request: rest_framework.request.Request
        :param uid: str
        :return: Response
        """
        response = {
            "detail": "",
            "status_code": KOBO_INTERNAL_ERROR_STATUS_CODE
        }
        status_code = status.HTTP_200_OK
        hook_log = self.get_object()

        if hook_log.can_retry():
            hook_log.change_status()
            success = hook_log.retry()
            if success:
                # Return status_code of remote server too.
                # `response["status_code"]` is not the same as `status_code`
                response["detail"] = hook_log.message
                response["status_code"] = hook_log.status_code
            else:
                response["detail"] = t(
                    "An error has occurred when sending the data. Please try again later."
                )
                status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
        else:
            response["detail"] = t(
                "Data is being or has already been processed")
            status_code = status.HTTP_400_BAD_REQUEST

        return Response(response, status=status_code)
示例#5
0
    def _validate_metadata(self,
                           metadata: dict,
                           validate_redirect_url: bool = False) -> dict:

        if metadata is None:
            raise serializers.ValidationError(
                {'metadata': t('This field is required')})

        if validate_redirect_url:
            try:
                metadata['redirect_url']
            except KeyError:
                raise serializers.ValidationError(
                    {'metadata': t('`redirect_url` is required')})
            else:
                parsed_url = urlparse(metadata['redirect_url'])
                metadata['filename'] = os.path.basename(parsed_url.path)

        try:
            metadata['filename']
        except KeyError:
            raise serializers.ValidationError(
                {'metadata': t('`filename` is required')})

        return metadata
示例#6
0
    def validate_source(self, source):
        asset = self.context['asset']

        if self.instance and self.instance.source_uid != source.uid:
            raise serializers.ValidationError(
                t('Source cannot be changed')
            )

        # Source data sharing must be enabled before going further
        if not source.data_sharing.get('enabled'):
            raise serializers.ValidationError(t(
                'Data sharing for `{source_uid}` is not enabled'
            ).format(source_uid=source.uid))

        # Validate whether owner of the asset is allowed to link their form
        # with the source. Validation is made with owner of the asset instead of
        # `request.user`
        required_perms = [
            PERM_PARTIAL_SUBMISSIONS,
            PERM_VIEW_SUBMISSIONS,
        ]
        if not source.has_perms(asset.owner, required_perms, all_=False):
            raise serializers.ValidationError(t(
                'Pairing data with `{source_uid}` is not allowed'
            ).format(source_uid=source.uid))

        if not self.instance and source.uid in asset.paired_data:
            raise serializers.ValidationError(t(
                'Source `{source}` is already paired'
            ).format(source=source.name))

        return source
示例#7
0
def export_list(request, username, id_string, export_type):
    try:
        Export.EXPORT_TYPE_DICT[export_type]
    except KeyError:
        return HttpResponseBadRequest(t('Invalid export type'))

    owner = get_object_or_404(User, username__iexact=username)
    xform = get_object_or_404(XForm, id_string__exact=id_string, user=owner)
    if not has_permission(xform, owner, request):
        return HttpResponseForbidden(t('Not shared.'))

    data = {
        'username':
        owner.username,
        'xform':
        xform,
        'export_type':
        export_type,
        'export_type_name':
        Export.EXPORT_TYPE_DICT[export_type],
        'exports':
        Export.objects.filter(xform=xform,
                              export_type=export_type).order_by('-created_on')
    }

    return render(request, 'export_list.html', data)
示例#8
0
def export_download(request, username, id_string, export_type, filename):
    owner = get_object_or_404(User, username__iexact=username)
    xform = get_object_or_404(XForm, id_string__exact=id_string, user=owner)
    helper_auth_helper(request)
    if not has_permission(xform, owner, request):
        return HttpResponseForbidden(t('Not shared.'))

    # find the export entry in the db
    export = get_object_or_404(Export, xform=xform, filename=filename)

    ext, mime_type = export_def_from_filename(export.filename)

    audit = {"xform": xform.id_string, "export_type": export.export_type}
    audit_log(
        Actions.EXPORT_DOWNLOADED, request.user, owner,
        t("Downloaded %(export_type)s export '%(filename)s' "
          "on '%(id_string)s'.") % {
              'export_type': export.export_type.upper(),
              'filename': export.filename,
              'id_string': xform.id_string,
          }, audit, request)
    if request.GET.get('raw'):
        id_string = None

    default_storage = get_storage_class()()
    if not isinstance(default_storage, FileSystemStorage):
        return HttpResponseRedirect(default_storage.url(export.filepath))

    basename = os.path.splitext(export.filename)[0]
    response = response_with_mimetype_and_name(mime_type,
                                               name=basename,
                                               extension=ext,
                                               file_path=export.filepath,
                                               show_date=False)
    return response
示例#9
0
def download_metadata(request, username, id_string, data_id):
    xform = get_object_or_404(XForm,
                              user__username__iexact=username,
                              id_string__exact=id_string)
    owner = xform.user
    # FIXME: couldn't non-owner users be allowed to access these files even
    # without the form being entirely public (shared=True)?
    if username == request.user.username or xform.shared:
        data = get_object_or_404(MetaData, pk=data_id)
        file_path = data.data_file.name
        filename, extension = os.path.splitext(file_path.split('/')[-1])
        extension = extension.strip('.')
        dfs = get_storage_class()()
        if dfs.exists(file_path):
            audit = {'xform': xform.id_string}
            audit_log(
                Actions.FORM_UPDATED, request.user, owner,
                t("Document '%(filename)s' for '%(id_string)s' downloaded.") %
                {
                    'id_string': xform.id_string,
                    'filename': "%s.%s" % (filename, extension)
                }, audit, request)
            response = response_with_mimetype_and_name(data.data_file_type,
                                                       filename,
                                                       extension=extension,
                                                       show_date=False,
                                                       file_path=file_path)
            return response
        else:
            return HttpResponseNotFound()

    return HttpResponseForbidden(t('Permission denied.'))
示例#10
0
def one_time_login(request):
    """
    If the request provides a key that matches a OneTimeAuthenticationKey
    object, log in the User specified in that object and redirect to the
    location specified in the 'next' parameter
    """
    try:
        key = request.POST['key']
    except KeyError:
        return HttpResponseBadRequest(t('No key provided'))
    try:
        next_ = request.GET['next']
    except KeyError:
        next_ = None
    if not next_ or not is_safe_url(url=next_, host=request.get_host()):
        next_ = resolve_url(settings.LOGIN_REDIRECT_URL)
    # Clean out all expired keys, just to keep the database tidier
    OneTimeAuthenticationKey.objects.filter(
        expiry__lt=datetime.datetime.now()).delete()
    with transaction.atomic():
        try:
            otak = OneTimeAuthenticationKey.objects.get(
                key=key,
                expiry__gte=datetime.datetime.now()
            )
        except OneTimeAuthenticationKey.DoesNotExist:
            return HttpResponseBadRequest(t('Invalid or expired key'))
        # Nevermore
        otak.delete()
    # The request included a valid one-time key. Log in the associated user
    user = otak.user
    user.backend = settings.AUTHENTICATION_BACKENDS[0]
    login(request, user)
    return HttpResponseRedirect(next_)
示例#11
0
    def bulk_validation_status(self, request, *args, **kwargs):

        xform = self.get_object()

        try:
            new_validation_status_uid = request.data['validation_status.uid']
        except KeyError:
            raise ValidationError({
                'payload': t('No `validation_status.uid` provided')
            })

        # Create new validation_status object
        new_validation_status = get_validation_status(
            new_validation_status_uid, xform, request.user.username)

        postgres_query, mongo_query = self.__build_db_queries(xform,
                                                              request.data)

        # Update Postgres & Mongo
        updated_records_count = Instance.objects.filter(
            **postgres_query
        ).update(validation_status=new_validation_status)
        ParsedInstance.bulk_update_validation_statuses(mongo_query,
                                                       new_validation_status)
        return Response({
            'detail': t('{} submissions have been updated').format(
                      updated_records_count)
        }, status.HTTP_200_OK)
示例#12
0
class ShowBasketSerializer(DefaultModelSerializer):
    ShopSerializer = ModelPresenter(Shop, (
        'id',
        'url',
        'name',
    ))
    ProductInfoSerializer = ModelPresenter(
        ProductInfo, ('id', 'url', 'product', 'shop', 'price', 'price_rrc'), {
            'product': serializers.StringRelatedField(),
            'shop': ShopSerializer()
        })
    OrderedItemsSerializer = ModelPresenter(
        OrderItem, ('id', 'product_info', 'quantity'),
        {'product_info': ProductInfoSerializer()})

    ordered_items = OrderedItemsSerializer(read_only=True,
                                           many=True,
                                           label=t('Заказанные товары'),
                                           help_text=t('Заказанные товары'))

    total_sum = serializers.DecimalField(read_only=True,
                                         max_digits=20,
                                         decimal_places=2,
                                         min_value=0,
                                         label=t('Total'),
                                         help_text=t('Общая сумма'))

    class Meta:
        model = Order
        fields = (
            'ordered_items',
            'total_sum',
            'Errors',
            'Status',
        )
示例#13
0
def kml_export(request, username, id_string):
    # read the locations from the database
    owner = get_object_or_404(User, username__iexact=username)
    xform = get_object_or_404(XForm, id_string__exact=id_string, user=owner)
    helper_auth_helper(request)
    if not has_permission(xform, owner, request):
        return HttpResponseForbidden(t('Not shared.'))
    data = {'data': kml_export_data(id_string, user=owner)}
    response = \
        render(request, "survey.kml", data,
               content_type="application/vnd.google-earth.kml+xml")
    response['Content-Disposition'] = \
        disposition_ext_and_date(id_string, 'kml')
    audit = {"xform": xform.id_string, "export_type": Export.KML_EXPORT}
    audit_log(
        Actions.EXPORT_CREATED, request.user, owner,
        t("Created KML export on '%(id_string)s'.") % {
            'id_string': xform.id_string,
        }, audit, request)
    # log download as well
    audit_log(
        Actions.EXPORT_DOWNLOADED, request.user, owner,
        t("Downloaded KML export on '%(id_string)s'.") % {
            'id_string': xform.id_string,
        }, audit, request)

    return response
示例#14
0
    def _get_response(
        self,
        request,
        submission_id_or_uuid: Union[str, int],
        attachment_id: Optional[int] = None,
        xpath: Optional[str] = None,
    ) -> Response:

        try:
            attachment = self.asset.deployment.get_attachment(
                submission_id_or_uuid, request.user, attachment_id, xpath)
        except (SubmissionNotFoundException, AttachmentNotFoundException):
            raise Http404
        except InvalidXPathException:
            raise serializers.ValidationError(
                {'detail': t('Invalid XPath syntax')}, 'invalid_xpath')
        except XPathNotFoundException:
            raise serializers.ValidationError(
                {'detail': t('The path could not be found in the submission')},
                'xpath_not_found')

        try:
            protected_path = attachment.protected_path(
                request.accepted_renderer.format)
        except FFMpegException:
            raise serializers.ValidationError(
                {'detail': t('The error occurred during conversion')},
                'ffmpeg_error')
        except NotSupportedFormatException:
            raise serializers.ValidationError(
                {
                    'detail':
                    t('Conversion is not supported for {}').format(
                        attachment.mimetype)
                }, 'not_supported_format')

        # If unit tests are running, pytest webserver does not support
        # `X-Accel-Redirect` header (or ignores it?). We need to pass
        # the content to the Response object
        if settings.TESTING:
            # setting the content type to `None` here allows the renderer to
            # specify the content type for the response
            content_type = (attachment.mimetype
                            if request.accepted_renderer.format !=
                            MP3ConversionRenderer.format else None)
            return Response(
                attachment.content,
                content_type=content_type,
            )

        # Otherwise, let NGINX determine the correct content type and serve
        # the file
        headers = {
            'Content-Disposition':
            f'inline; filename={attachment.media_file_basename}',
            'X-Accel-Redirect': protected_path
        }
        response = Response(content_type='', headers=headers)
        return response
示例#15
0
 class Meta:
     ordering = ('-completed', '-created')
     get_latest_by = ('created', )
     permissions = (
         ('rerun', t('Can rerun failed tasks.')),
         ('cancel', t('Can cancel failed tasks.')),
     )
     default_manager_name = 'objects'
示例#16
0
 class Meta:
     ordering = ("-completed", "-created")
     get_latest_by = ("created", )
     permissions = (
         ("rerun", t("Can rerun failed tasks.")),
         ("cancel", t("Can cancel failed tasks.")),
     )
     default_manager_name = "objects"
示例#17
0
    def _validate_filename(self, attrs: dict):

        if self.instance and 'filename' not in attrs:
            return

        asset = self.context['asset']
        source = attrs['source']
        filename, extension = os.path.splitext(attrs['filename'])

        if not re.match(r'^[\w\d-]+$', filename):
            raise serializers.ValidationError(
                {
                    'filename': t('Only letters, numbers and `-` are allowed')
                }
            )

        if extension.lower() != '.xml' and extension != '':
            raise serializers.ValidationError(
                {
                    'filename': t('Extension must be `xml`')
                }
            )

        # force XML extension
        basename = filename
        filename = f'{filename}.xml'

        # Validate uniqueness of `filename`
        # It cannot be used by any other asset files
        media_filenames = (
            AssetFile.objects.values_list('metadata__filename', flat=True)
            .filter(asset_id=asset.pk)
            .exclude(file_type=AssetFile.PAIRED_DATA)
        )

        paired_data_filenames = {}
        for p_uid, values in asset.paired_data.items():
            paired_data_filenames[p_uid] = values['filename']

        pd_filename = paired_data_filenames.get(source.uid)
        is_new = pd_filename is None

        if (
            filename in media_filenames
            or (
                filename in paired_data_filenames.values()
                and (is_new or (not is_new and pd_filename != filename))
            )
        ):
            raise serializers.ValidationError(
                {
                    'filename': t(
                        '`{basename}` is already used'
                    ).format(basename=basename)
                }
            )

        attrs['filename'] = filename
示例#18
0
class PartnerUpdateSchema(ResponsesSchema):
    """
    Класс документирует partner-update
    (добавляет статус коды в openapi документацию)
    """
    status_descriptions = {
        '201': t('Created'),
        '404': t('URL не найден'),
    }
示例#19
0
class ConfirmUserSerializer(DefaultSerializer):
    email = serializers.EmailField(required=True,
                                   allow_blank=False,
                                   label=t('Email'),
                                   help_text=t('Iput email'))
    token = serializers.CharField(required=True,
                                  allow_blank=False,
                                  label=t('Auth token'),
                                  help_text=t('Auth token'))
示例#20
0
def bulksubmission(request, username):
    # puts it in a temp directory.
    # runs "import_tools(temp_directory)"
    # deletes
    posting_user = get_object_or_404(User, username__iexact=username)

    # request.FILES is a django.utils.datastructures.MultiValueDict
    # for each key we have a list of values
    try:
        temp_postfile = request.FILES.pop("zip_submission_file", [])
    except IOError:
        return HttpResponseBadRequest(
            t("There was a problem receiving your "
              "ODK submission. [Error: IO Error "
              "reading data]"))
    if len(temp_postfile) != 1:
        return HttpResponseBadRequest(
            t("There was a problem receiving your"
              " ODK submission. [Error: multiple "
              "submission files (?)]"))

    postfile = temp_postfile[0]
    tempdir = tempfile.gettempdir()
    our_tfpath = os.path.join(tempdir, postfile.name)

    with open(our_tfpath, 'wb') as f:
        f.write(postfile.read())

    with open(our_tfpath, 'rb') as f:
        total_count, success_count, errors = import_instances_from_zip(
            f, posting_user)
    # chose the try approach as suggested by the link below
    # http://stackoverflow.com/questions/82831
    try:
        os.remove(our_tfpath)
    except IOError:
        # TODO: log this Exception somewhere
        pass
    json_msg = {
        'message': t("Submission complete. Out of %(total)d "
                     "survey instances, %(success)d were imported, "
                     "(%(rejected)d were rejected as duplicates, "
                     "missing forms, etc.)") % {
                         'total': total_count,
                         'success': success_count,
                         'rejected': total_count - success_count
                     },
        'errors': "%d %s" % (len(errors), errors)
    }
    audit = {"bulk_submission_log": json_msg}
    audit_log(Actions.USER_BULK_SUBMISSION, request.user, posting_user,
              t("Made bulk submissions."), audit, request)
    response = HttpResponse(json.dumps(json_msg))
    response.status_code = 200
    response['Location'] = request.build_absolute_uri(request.path)
    return response
示例#21
0
    def check_for_migration_from_shared_database(self):
        def db_contains_app_migrations(db_connection, app):
            # Does the migrations table exist?
            with db_connection.cursor() as cursor:
                cursor.execute('''SELECT (1) AS "exists" FROM "pg_tables" '''
                               '''WHERE "tablename" = 'django_migrations' '''
                               '''LIMIT 1;''')
                if not cursor.fetchone():
                    return False
            # Does the migrations table contain any KPI migration?
            with db_connection.cursor() as cursor:
                cursor.execute(
                    '''SELECT (1) AS "exists" FROM "django_migrations" '''
                    '''WHERE "app" = %s '''
                    '''LIMIT 1;''', [app])
                if not cursor.fetchone():
                    return False
            return True

        kpi_connection = connections['default']
        kc_connection = connections['kobocat']
        kpi_app = 'kpi'
        kc_app = 'logger'

        if db_contains_app_migrations(kc_connection, kpi_app):
            # This was formerly a single-database setup, since the KC database
            # contains KPI migrations
            if not db_contains_app_migrations(kpi_connection, kc_app):
                # When migrating from the single, shared database setup:
                #   1. A new database for KPI should have been created;
                #   2. Certain tables, including `django_migrations`, should
                #      have been copied from the original, shared database to
                #      the new one;
                #   3. KoBoCAT should have been configured to continue using
                #      the original database;
                #   4. KPI should have been configured to use the newly-created
                #      database;
                #   5. Because `django_migrations` should have been copied from
                #      the original database to the new one, we should see
                #      KoBoCAT migrations in the KPI database.
                # Since we _do not_ see any KoBoCAT migrations, stop now and
                # get the human to fix their installation.
                self.errors.append(
                    Error(
                        t('Incomplete migration from shared-database installation'
                          ),
                        hint=t(
                            'The KoBoCAT database was originally shared by '
                            'KPI, but the KPI tables were not copied from that '
                            'shared database to the new, KPI-only database.') +
                        self.guidance_message,
                        obj=self,
                        id='KPI.E023',
                    ))
                return False
        return True
示例#22
0
class DefaultSerializer(serializers.Serializer):
    """
    Базовый класс сериалайзера с полями для документирования ошибок и статуса
    """
    Errors = serializers.CharField(read_only=True,
                                   help_text=t('Error message(s)'),
                                   label=t('Error'))
    Status = serializers.BooleanField(read_only=True,
                                      help_text=t('Http Status code'),
                                      label=t('Status code'))
示例#23
0
文件: hook.py 项目: kobotoolbox/kpi
 def validate_endpoint(self, value):
     """
     Check if endpoint is valid
     """
     if not value.startswith('http'):
         raise serializers.ValidationError(t('Invalid scheme'))
     elif not constance.config.ALLOW_UNSECURED_HOOK_ENDPOINTS and \
             value.startswith('http:'):
         raise serializers.ValidationError(
             t('Unsecured endpoint is not allowed'))
     return value
示例#24
0
 def report_error(user):
     send_multi_alternative.delay(
         # title:
         t('Не удалось обновить прайс'),
         # message:
         t('Произошла ошибка при обновлении прайса'),
         # from:
         settings.EMAIL_HOST_USER,
         # to:
         [user.email]
     )
示例#25
0
 def report_success(user):
     send_multi_alternative.delay(
         # title:
         t('Обновление прайс листов завершено'),
         # message:
         t('Все возможные прайс листы обновлены'),
         # from:
         settings.EMAIL_HOST_USER,
         # to:
         [user.email]
     )
示例#26
0
    def validate_xform(self, xform):
        request = self.context.get('request')

        if not request.user.has_perm(CAN_VIEW_XFORM, xform):
            raise serializers.ValidationError(t('Project not found'))

        if not request.user.has_perm(CAN_CHANGE_XFORM, xform):
            raise serializers.ValidationError(
                t('You do not have sufficient permissions to perform this action'
                  ))

        return xform
示例#27
0
    def validate_fields(self, data: dict) -> list:
        fields = data[EXPORT_SETTING_FIELDS]
        if not isinstance(fields, list):
            raise serializers.ValidationError(
                {EXPORT_SETTING_FIELDS: t('Must be an array')})

        if not all((isinstance(field, str) for field in fields)):
            raise serializers.ValidationError({
                EXPORT_SETTING_FIELDS:
                t('All values in the array must be strings')
            })
        return fields
示例#28
0
 def clean(self, value):
     try:
         instance = json.loads(value)
         jsonschema.validate(instance, self.schema)
     except json.JSONDecodeError as e:
         # Message written to match `IntegerField`, which uses the
         # imperative: "Enter a whole number."
         raise ValidationError(t('Enter valid JSON.') + ' ' + str(e))
     except jsonschema.exceptions.ValidationError as e:
         # `str(e)` is too verbose (it includes the entire schema)
         raise ValidationError(t('Enter valid JSON.') + ' ' + e.message)
     return value
示例#29
0
    def validate_submission_ids(self, data: dict) -> list:
        submission_ids = data[EXPORT_SETTING_SUBMISSION_IDS]
        if not isinstance(submission_ids, list):
            raise serializers.ValidationError(
                {EXPORT_SETTING_SUBMISSION_IDS: t('Must be an array')})

        if (submission_ids
                and not all(isinstance(_id, int) for _id in submission_ids)):
            raise serializers.ValidationError({
                EXPORT_SETTING_SUBMISSION_IDS:
                t('All values in the array must be integers')
            })
        return submission_ids
示例#30
0
def download_xlsform(request, username, id_string):
    xform = get_object_or_404(XForm,
                              user__username__iexact=username,
                              id_string__exact=id_string)
    owner = User.objects.get(username__iexact=username)
    helper_auth_helper(request)

    if not has_permission(xform, owner, request, xform.shared):
        return HttpResponseForbidden('Not shared.')

    file_path = xform.xls.name
    default_storage = get_storage_class()()

    if file_path != '' and default_storage.exists(file_path):
        audit = {"xform": xform.id_string}
        audit_log(
            Actions.FORM_XLS_DOWNLOADED, request.user, xform.user,
            t("Downloaded XLS file for form '%(id_string)s'.") %
            {"id_string": xform.id_string}, audit, request)

        if file_path.endswith('.csv'):
            with default_storage.open(file_path) as ff:
                xls_io = convert_csv_to_xls(ff.read())
                response = StreamingHttpResponse(
                    xls_io,
                    content_type='application/vnd.ms-excel; charset=utf-8')
                response[
                    'Content-Disposition'] = 'attachment; filename=%s.xls' % xform.id_string
                return response

        split_path = file_path.split(os.extsep)
        extension = 'xls'

        if len(split_path) > 1:
            extension = split_path[len(split_path) - 1]

        response = response_with_mimetype_and_name('vnd.ms-excel',
                                                   id_string,
                                                   show_date=False,
                                                   extension=extension,
                                                   file_path=file_path)

        return response

    else:
        messages.add_message(
            request, messages.WARNING,
            t('No XLS file for your form '
              '<strong>%(id)s</strong>') % {'id': id_string})

        return HttpResponseRedirect("/%s" % username)
示例#31
0
def send_email_for_message(message):
    send_mail(t('You are Hero - new Message - %s') % message.title,
        message.text,
        '*****@*****.**',
        [message.recipient.email],
        fail_silently=True
    )