예제 #1
0
    def test_retrieve_view(self):
        self._submit_transport_instance_w_attachment()

        pk = self.attachment.pk
        data = {
            'url': 'http://testserver/api/v1/media/%s' % pk,
            'field_xpath': None,
            'download_url': self.attachment.media_file.url,
            'small_download_url': image_url(self.attachment, 'small'),
            'medium_download_url': image_url(self.attachment, 'medium'),
            'id': pk,
            'xform': self.xform.pk,
            'instance': self.attachment.instance.pk,
            'mimetype': self.attachment.mimetype,
            'filename': self.attachment.media_file.name
        }
        request = self.factory.get('/', **self.extra)
        response = self.retrieve_view(request, pk=pk)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(isinstance(response.data, dict))
        self.assertEqual(response.data, data)

        # file download
        filename = data['filename']
        ext = filename[filename.rindex('.') + 1:]
        request = self.factory.get('/', **self.extra)
        response = self.retrieve_view(request, pk=pk, format=ext)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content_type, 'image/jpeg')
    def test_retrieve_view(self):
        self._submit_transport_instance_w_attachment()

        pk = self.attachment.pk
        data = {
            'url': 'http://testserver/api/v1/media/%s' % pk,
            'field_xpath': None,
            'download_url': self.attachment.media_file.url,
            'small_download_url': image_url(self.attachment, 'small'),
            'medium_download_url': image_url(self.attachment, 'medium'),
            'id': pk,
            'xform': self.xform.pk,
            'instance': self.attachment.instance.pk,
            'mimetype': self.attachment.mimetype,
            'filename': self.attachment.media_file.name
        }
        request = self.factory.get('/', **self.extra)
        response = self.retrieve_view(request, pk=pk)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(isinstance(response.data, dict))
        self.assertEqual(response.data, data)

        # file download
        filename = data['filename']
        ext = filename[filename.rindex('.') + 1:]
        request = self.factory.get('/', **self.extra)
        response = self.retrieve_view(request, pk=pk, format=ext)
        self.assertNotEqual(response.get('Last-Modified'), None)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.content_type, 'image/jpeg')
예제 #3
0
def get_attachment_data(attachment, suffix):
    if suffix in list(settings.THUMB_CONF):
        image_url(attachment, suffix)
        suffix = settings.THUMB_CONF.get(suffix).get('suffix')
        f = default_storage.open(get_path(attachment.media_file.name, suffix))
        data = f.read()
    else:
        data = attachment.media_file.read()

    return data
예제 #4
0
def get_attachment_data(attachment, suffix):
    if suffix in settings.THUMB_CONF.keys():
        image_url(attachment, suffix)
        suffix = settings.THUMB_CONF.get(suffix).get('suffix')
        f = default_storage.open(
            get_path(attachment.media_file.name, suffix))
        data = f.read()
    else:
        data = attachment.media_file.read()

    return data
예제 #5
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file
    result = Attachment.objects.filter(media_file=media_file)[0:1]
    if result.count() == 0:
        pattern = re.compile('(.*)-(\d+)_(\d+)_(\d+)\.(.*)')
        m = pattern.search(media_file)
        if m:
            pattern = re.compile('(.*)-(.*)\.(.*)')
            m = pattern.search(media_file)
            media_file = media_file.replace("-"+m.group(2), "")
            result = Attachment.objects.filter(media_file=media_file)[0:1]
        else:
            return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)
    try:
        media_url = image_url(attachment, size)
    except:
        # TODO: log this somewhere
        # image not found, 404, S3ResponseError timeouts
        pass
    else:
        if media_url:
            return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #6
0
파일: views.py 프로젝트: onaio/onadata
def attachment_url(request, size='medium'):
    """
    Redirects to image attachment  of the specified size, defaults to 'medium'.
    """
    media_file = request.GET.get('media_file')
    no_redirect = request.GET.get('no_redirect')
    if not media_file:
        return HttpResponseNotFound(_(u'Attachment not found'))

    result = Attachment.objects.filter(media_file=media_file).order_by()[0:1]
    if not result:
        return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]

    if size == 'original' and no_redirect == 'true':
        response = response_with_mimetype_and_name(
            attachment.mimetype,
            attachment.name,
            extension=attachment.extension,
            file_path=attachment.media_file.name)

        return response
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)
    media_url = image_url(attachment, size)
    if media_url:
        return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #7
0
def attachment_url(request, size='medium'):
    """
    Redirects to image attachment  of the specified size, defaults to 'medium'.
    """
    media_file = request.GET.get('media_file')
    no_redirect = request.GET.get('no_redirect')
    if not media_file:
        return HttpResponseNotFound(_(u'Attachment not found'))

    result = Attachment.objects.filter(media_file=media_file)[0:1]
    if result.count() == 0:
        return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]

    if size == 'original' and no_redirect == 'true':
        response = response_with_mimetype_and_name(
            attachment.mimetype,
            attachment.name,
            extension=attachment.extension,
            file_path=attachment.media_file.name)

        return response
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)
    media_url = image_url(attachment, size)
    if media_url:
        return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #8
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    no_redirect = request.GET.get('no_redirect')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file
    result = Attachment.objects.filter(media_file=media_file)[0:1]
    if result.count() == 0:
        return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]

    if size == 'original' and no_redirect == 'true':
        response = response_with_mimetype_and_name(
            attachment.mimetype,
            attachment.name,
            extension=attachment.extension,
            file_path=attachment.media_file.name)

        return response
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)
    try:
        media_url = image_url(attachment, size)
    except:
        # TODO: log this somewhere
        # image not found, 404, S3ResponseError timeouts
        pass
    else:
        if media_url:
            return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #9
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file
    if media_file:
        mtch = re.search('^([^\/]+)/attachments(/[^\/]+)$', media_file)
        if mtch:
            # in cases where the media_file url created by instance.html's
            # _attachment_url function is in the wrong format, this will
            # match attachments with the correct owner and the same file name
            (username, filename) = mtch.groups()
            result = Attachment.objects.filter(**{
                  'instance__xform__user__username': username,
                }).filter(**{
                  'media_file__endswith': filename,
                })[0:1]
        else:
            # search for media_file with exact matching name
            result = Attachment.objects.filter(media_file=media_file)[0:1]
    if result.count() == 0:
        media_file_logger.info('attachment not found')
        return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)

    try:
        media_url = image_url(attachment, size)
    except:
        media_file_logger.error('could not get thumbnail for image', exc_info=True)
    else:
        if media_url:
            return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #10
0
    def append_row(self, question_name, question_label, question_type,
                   answer_dict):
        styNormal = self.bodystyle
        styBackground = ParagraphStyle('background',
                                       parent=styNormal,
                                       backColor=colors.white)

        if question_name in answer_dict:
            if question_type == 'note':
                answer = Paragraph('', styBackground)
                isNull = True

            elif question_type == 'photo':
                #photo = '/media/user/attachments/'+ r_answer[r_question+"/"+question]

                size = "small"
                try:
                    result = Attachment.objects.filter(
                        media_file=self.media_folder + '/attachments/' +
                        answer_dict[question_name])[0:1]
                    attachment = result[0]

                    if not attachment.mimetype.startswith('image'):
                        media_url = 'http://' + self.base_url + '/static/images/img-404.jpg'

                    media_url = image_url(attachment, size)

                except:
                    media_url = 'http://' + self.base_url + '/static/images/img-404.jpg'

                answer = self.create_logo(media_url)
                isNull = False
                # answer =''
            elif question_type == 'audio' or question_type == 'video':
                media_link = 'http://' + self.base_url + '/attachment/medium?media_file=' + self.media_folder + '/attachments/' + answer_dict[
                    question_name]
                answer = Paragraph(
                    '<link href="' + media_link + '">Attachment</link>',
                    styBackground)
                isNull = False
            else:
                answer_text = answer_dict[question_name]
                if len(answer_text) > 1200:
                    new_answer_text = answer_text[0:360]
                    answer_text = new_answer_text + ".... ( full answer followed after this table. )"
                    self.additional_data.append(
                        {question_label: answer_dict[question_name]})

                answer = Paragraph(answer_text, styBackground)
                isNull = False
        else:
            answer = Paragraph('', styBackground)
            isNull = True

        if self.removeNullField and isNull:
            pass
        else:
            row = [Paragraph(question_label, styBackground), answer]
            self.data.append(row)
예제 #11
0
 def test_thumbnails(self):
     for attachment in Attachment.objects.filter(instance=self.instance):
         url = image_url(attachment, 'small')
         filename = attachment.media_file.name.replace('.jpg', '')
         thumbnail = '%s-small.jpg' % filename
         self.assertNotEqual(url.find(thumbnail), -1)
         for size in ['small', 'medium', 'large']:
             thumbnail = f'{filename}-{size}.jpg'
             self.assertTrue(default_storage.exists(thumbnail))
             default_storage.delete(thumbnail)
예제 #12
0
 def test_thumbnails(self):
     for attachment in Attachment.objects.filter(instance=self.instance):
         url = image_url(attachment, 'small')
         filename = attachment.media_file.name.replace('.jpg', '')
         thumbnail = '%s-small.jpg' % filename
         self.assertNotEqual(
             url.find(thumbnail), -1)
         for size in ['small', 'medium', 'large']:
             thumbnail = '%s-%s.jpg' % (filename, size)
             self.assertTrue(
                 default_storage.exists(thumbnail))
             default_storage.delete(thumbnail)
예제 #13
0
    def retrieve(self, request, pk=None):
        """
        Redirect to final attachment url

        param pk: the attachment id
        query param filename: the filename of the associated attachment is
            required and has to match
        query param suffix: (optional) - specify small | medium | large to
            return resized images.

        return HttpResponseRedirect: redirects to final image url
        """
        try:
            int(pk)
        except ValueError:
            raise Http404()
        else:
            filename = request.query_params.get('filename')
            attachments = Attachment.objects.all()
            obj = get_object_or_404(attachments, pk=pk)

            if obj.media_file.name != filename:
                raise Http404()

            url = None

            if obj.mimetype.startswith('image'):
                suffix = request.query_params.get('suffix')

                if suffix:
                    if suffix in list(settings.THUMB_CONF):
                        try:
                            url = image_url(obj, suffix)
                        except Exception as e:
                            raise ParseError(e)
                    else:
                        raise Http404()

            if not url:
                response = generate_media_download_url(obj)

                return response

            return HttpResponseRedirect(url)

        raise Http404()
예제 #14
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file
    result = Attachment.objects.filter(media_file=media_file)[0:1]
    if result.count() == 0:
        return HttpResponseNotFound(_(u'Attachment not found'))
    attachment = result[0]
    if not attachment.mimetype.startswith('image'):
        return redirect(attachment.media_file.url)
    try:
        media_url = image_url(attachment, size)
    except:
        # TODO: log this somewhere
        # image not found, 404, S3ResponseError timeouts
        pass
    else:
        if media_url:
            return redirect(media_url)
    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #15
0
    def retrieve(self, request, pk=None):
        """
        Redirect to final attachment url

        param pk: the attachment id
        query param filename: the filename of the associated attachment is
            required and has to match
        query param suffix: (optional) - specify small | medium | large to
            retuurn resized images.

        return HttpResponseRedirect: redirects to final image url
        """
        try:
            int(pk)
        except ValueError:
            raise Http404()
        else:
            filename = request.QUERY_PARAMS.get('filename')
            attachments = Attachment.objects.all()
            obj = get_object_or_404(attachments, pk=pk)

            if obj.media_file.name != filename:
                raise Http404()

            url = None

            if obj.mimetype.startswith('image'):
                suffix = request.QUERY_PARAMS.get('suffix')

                if suffix:
                    if suffix in settings.THUMB_CONF.keys():
                        url = image_url(obj, suffix)
                    else:
                        raise Http404()

            if not url:
                url = obj.media_file.url

            return HttpResponseRedirect(url)

        raise Http404()
예제 #16
0
파일: views.py 프로젝트: djkobraz/kobocat
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file
    if media_file:
        mtch = re.search('^([^\/]+)/attachments(/[^\/]+)$', media_file)
        if mtch:
            # in cases where the media_file url created by instance.html's
            # _attachment_url function is in the wrong format, this will
            # match attachments with the correct owner and the same file name
            (username, filename) = mtch.groups()
            result = Attachment.objects.filter(
                **{
                    'instance__xform__user__username': username,
                }).filter(**{
                    'media_file__endswith': filename,
                })[0:1]
        else:
            # search for media_file with exact matching name
            result = Attachment.objects.filter(media_file=media_file)[0:1]

        if len(result) == 0:
            media_file_logger.info('attachment not found')
            return HttpResponseNotFound(_(u'Attachment not found'))

        attachment = result[0]

        if not attachment.mimetype.startswith('image'):
            return redirect(attachment.media_file.url)

        try:
            media_url = image_url(attachment, size)
        except:
            media_file_logger.error('could not get thumbnail for image',
                                    exc_info=True)
        else:
            if media_url:
                return redirect(media_url)

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #17
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file.
    #
    # Django seems to already handle that. It appends datetime to the filename.
    # It means duplicated would be only for the same user who uploaded two files
    # with same name at the same second.
    if media_file:
        mtch = re.search(r'^([^/]+)/attachments/([^/]+)$', media_file)
        if mtch:
            # in cases where the media_file url created by instance.html's
            # _attachment_url function is in the wrong format, this will
            # match attachments with the correct owner and the same file name
            (username, filename) = mtch.groups()
            result = Attachment.objects.filter(
                instance__xform__user__username=username, ).filter(
                    Q(media_file_basename=filename)
                    | Q(media_file_basename=None,
                        media_file__endswith='/' + filename))[0:1]
        else:
            # search for media_file with exact matching name
            result = Attachment.objects.filter(media_file=media_file)[0:1]

        try:
            attachment = result[0]
            return redirect(attachment.media_file.url)
        except IndexError:
            media_file_logger.info('attachment not found')
            return HttpResponseNotFound(_(u'Attachment not found'))

        # Checks whether users are allowed to see the media file before giving them
        # the url
        xform = attachment.instance.xform

        if not request.user.is_authenticated():
            # This is not a DRF view, but we need to honor things like
            # `DigestAuthentication` (ODK Briefcase uses it!) and
            # `TokenAuthentication`. Let's try all the DRF authentication
            # classes before giving up
            drf_request = rest_framework.request.Request(request)
            for auth_class in api_settings.DEFAULT_AUTHENTICATION_CLASSES:
                auth_tuple = auth_class().authenticate(drf_request)
                if auth_tuple is not None:
                    # Is it kosher to modify `request`? Let's do it anyway
                    # since that's what `has_permission()` requires...
                    request.user = auth_tuple[0]
                    # `DEFAULT_AUTHENTICATION_CLASSES` are ordered and the
                    # first match wins; don't look any further
                    break

        if not has_permission(xform, xform.user, request):
            return HttpResponseForbidden(_(u'Not shared.'))

        media_url = None

        if not attachment.mimetype.startswith('image'):
            media_url = attachment.media_file.url
        else:
            try:
                media_url = image_url(attachment, size)
            except:
                media_file_logger.error('could not get thumbnail for image',
                                        exc_info=True)

        if media_url:
            # We want nginx to serve the media (instead of redirecting the media itself)
            # PROS:
            # - It avoids revealing the real location of the media.
            # - Full control on permission
            # CONS:
            # - When using S3 Storage, traffic is multiplied by 2.
            #    S3 -> Nginx -> User
            response = HttpResponse()
            default_storage = get_storage_class()()
            if not isinstance(default_storage, FileSystemStorage):
                # Double-encode the S3 URL to take advantage of NGINX's
                # otherwise troublesome automatic decoding
                # protected_url = '/protected-s3/{}'.format(urlquote(media_url))
                return redirect(media_url)
            else:
                return redirect(media_url)
                # protected_url = media_url.replace(settings.MEDIA_URL, "/protected/")

            # Let nginx determine the correct content type
            response["Content-Type"] = ""
            response["X-Accel-Redirect"] = protected_url
            return response

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #18
0
def attachment_url(request, size='medium'):
    media_file = request.GET.get('media_file')
    # TODO: how to make sure we have the right media file,
    # this assumes duplicates are the same file.
    #
    # Django seems to already handle that. It appends datetime to the filename.
    # It means duplicated would be only for the same user who uploaded two files
    # with same name at the same second.
    if media_file:
        mtch = re.search(r'^([^/]+)/attachments/([^/]+)$', media_file)
        if mtch:
            # in cases where the media_file url created by instance.html's
            # _attachment_url function is in the wrong format, this will
            # match attachments with the correct owner and the same file name
            (username, filename) = mtch.groups()
            result = Attachment.objects.filter(
                    instance__xform__user__username=username,
                ).filter(
                    Q(media_file_basename=filename) | Q(
                        media_file_basename=None,
                        media_file__endswith='/' + filename
                    )
                )[0:1]
        else:
            # search for media_file with exact matching name
            result = Attachment.objects.filter(media_file=media_file)[0:1]

        try:
            attachment = result[0]
        except IndexError:
            media_file_logger.info('attachment not found')
            return HttpResponseNotFound(_(u'Attachment not found'))

        # Checks whether users are allowed to see the media file before giving them
        # the url
        xform = attachment.instance.xform

        if not request.user.is_authenticated():
            # This is not a DRF view, but we need to honor things like
            # `DigestAuthentication` (ODK Briefcase uses it!) and
            # `TokenAuthentication`. Let's try all the DRF authentication
            # classes before giving up
            drf_request = rest_framework.request.Request(request)
            for auth_class in api_settings.DEFAULT_AUTHENTICATION_CLASSES:
                auth_tuple = auth_class().authenticate(drf_request)
                if auth_tuple is not None:
                    # Is it kosher to modify `request`? Let's do it anyway
                    # since that's what `has_permission()` requires...
                    request.user = auth_tuple[0]
                    # `DEFAULT_AUTHENTICATION_CLASSES` are ordered and the
                    # first match wins; don't look any further
                    break

        if not has_permission(xform, xform.user, request):
            return HttpResponseForbidden(_(u'Not shared.'))

        media_url = None

        if not attachment.mimetype.startswith('image'):
            media_url = attachment.media_file.url
        else:
            try:
                media_url = image_url(attachment, size)
            except:
                media_file_logger.error('could not get thumbnail for image', exc_info=True)

        if media_url:
            # We want nginx to serve the media (instead of redirecting the media itself)
            # PROS:
            # - It avoids revealing the real location of the media.
            # - Full control on permission
            # CONS:
            # - When using S3 Storage, traffic is multiplied by 2.
            #    S3 -> Nginx -> User
            response = HttpResponse()
            default_storage = get_storage_class()()
            if not isinstance(default_storage, FileSystemStorage):
                # Double-encode the S3 URL to take advantage of NGINX's
                # otherwise troublesome automatic decoding
                protected_url = '/protected-s3/{}'.format(urlquote(media_url))
            else:
                protected_url = media_url.replace(settings.MEDIA_URL, "/protected/")

            # Let nginx determine the correct content type
            response["Content-Type"] = ""
            response["X-Accel-Redirect"] = protected_url
            return response

    return HttpResponseNotFound(_(u'Error: Attachment not found'))
예제 #19
0
 def get_medium_download_url(self, obj):
     if obj.mimetype.startswith('image'):
         return image_url(obj, 'medium')
예제 #20
0
 def get_small_download_url(self, obj):
     if obj.mimetype.startswith('image'):
         return image_url(obj, 'small')
예제 #21
0
 def get_medium_download_url(self, obj):
     if obj.mimetype.startswith('image'):
         return image_url(obj, 'medium')
예제 #22
0
 def get_small_download_url(self, obj):
     if obj.mimetype.startswith('image'):
         return image_url(obj, 'small')