Ejemplo n.º 1
0
    def test_filtering_tags(self):
        get_image_model().objects.get(id=6).tags.add('test')

        response = self.get_response(tags='test')
        content = json.loads(response.content.decode('UTF-8'))

        image_id_list = self.get_image_id_list(content)
        self.assertEqual(image_id_list, [6])
Ejemplo n.º 2
0
    def test_offset_total_count(self):
        response = self.get_response(offset=10)
        content = json.loads(response.content.decode('UTF-8'))

        # The total count must not be affected by "offset"
        self.assertEqual(content['meta']['total_count'],
                         get_image_model().objects.count())
Ejemplo n.º 3
0
def register_signal_handlers():
    Image = get_image_model()
    Rendition = Image.get_rendition_model()

    pre_save.connect(pre_save_image_feature_detection, sender=Image)
    post_delete.connect(post_delete_file_cleanup, sender=Image)
    post_delete.connect(post_delete_file_cleanup, sender=Rendition)
Ejemplo n.º 4
0
def usage(request, image_id):
    image = get_object_or_404(get_image_model(), id=image_id)

    paginator, used_by = paginate(request, image.get_usage())

    return render(request, "tuiuiuimages/images/usage.html", {
        'image': image,
        'used_by': used_by
    })
Ejemplo n.º 5
0
    def test_tags(self):
        image = get_image_model().objects.get(id=5)
        image.tags.add('hello')
        image.tags.add('world')

        response = self.get_response(5)
        content = json.loads(response.content.decode('UTF-8'))

        self.assertIn('tags', content['meta'])
        self.assertEqual(content['meta']['tags'], ['hello', 'world'])
Ejemplo n.º 6
0
 def setUpTestData(cls):
     image_model = get_image_model()
     cls.test_image_1 = image_model.objects.create(
         title="Test image 1",
         file=get_test_image_file(),
     )
     cls.test_image_2 = image_model.objects.create(
         title="Test image 2",
         file=get_test_image_file(),
     )
Ejemplo n.º 7
0
    def test_custom_image_signal_handlers(self):
        #: Sadly signal receivers only get connected when starting django.
        #: We will re-attach them here to mimic the django startup behavior
        #: and get the signals connected to our custom model..
        signal_handlers.register_signal_handlers()

        image = get_image_model().objects.create(title="Test CustomImage", file=get_test_image_file())
        image_path = image.file.path
        image.delete()

        self.assertFalse(os.path.exists(image_path))
Ejemplo n.º 8
0
def unregister_signal_handlers():
    Image = get_image_model()
    Document = get_document_model()

    for model in get_page_models():
        page_published.disconnect(purge_page_from_cache, sender=model)
        page_unpublished.disconnect(purge_page_from_cache, sender=model)

    post_save.disconnect(purge_image_from_cache, sender=Image)
    post_delete.disconnect(purge_image_from_cache, sender=Image)
    post_save.disconnect(purge_document_from_cache, sender=Document)
    post_delete.disconnect(purge_document_from_cache, sender=Document)
Ejemplo n.º 9
0
def preview(request, image_id, filter_spec):
    image = get_object_or_404(get_image_model(), id=image_id)

    try:
        response = HttpResponse()
        image = Filter(spec=filter_spec).run(image, response)
        response['Content-Type'] = 'image/' + image.format_name
        return response
    except InvalidFilterSpecError:
        return HttpResponse("Invalid filter spec: " + filter_spec,
                            content_type='text/plain',
                            status=400)
Ejemplo n.º 10
0
def delete(request, image_id):
    image = get_object_or_404(get_image_model(), id=image_id)

    if not request.is_ajax():
        return HttpResponseBadRequest("Cannot POST to this view without AJAX")

    if not permission_policy.user_has_permission_for_instance(request.user, 'delete', image):
        raise PermissionDenied

    image.delete()

    return JsonResponse({
        'success': True,
        'image_id': int(image_id),
    })
Ejemplo n.º 11
0
def chooser_select_format(request, image_id):
    image = get_object_or_404(get_image_model(), id=image_id)

    if request.method == 'POST':
        form = ImageInsertionForm(request.POST,
                                  initial={'alt_text': image.default_alt_text})
        if form.is_valid():

            format = get_image_format(form.cleaned_data['format'])
            preview_image = image.get_rendition(format.filter_spec)

            image_json = json.dumps({
                'id':
                image.id,
                'title':
                image.title,
                'format':
                format.name,
                'alt':
                form.cleaned_data['alt_text'],
                'class':
                format.classnames,
                'edit_link':
                reverse('tuiuiuimages:edit', args=(image.id, )),
                'preview': {
                    'url': preview_image.url,
                    'width': preview_image.width,
                    'height': preview_image.height,
                },
                'html':
                format.image_to_editor_html(image,
                                            form.cleaned_data['alt_text']),
            })

            return render_modal_workflow(
                request, None, 'tuiuiuimages/chooser/image_chosen.js',
                {'image_json': image_json})
    else:
        initial = {'alt_text': image.default_alt_text}
        initial.update(request.GET.dict())
        form = ImageInsertionForm(initial=initial)

    return render_modal_workflow(request,
                                 'tuiuiuimages/chooser/select_format.html',
                                 'tuiuiuimages/chooser/select_format.js', {
                                     'image': image,
                                     'form': form
                                 })
Ejemplo n.º 12
0
def delete(request, image_id):
    image = get_object_or_404(get_image_model(), id=image_id)

    if not permission_policy.user_has_permission_for_instance(
            request.user, 'delete', image):
        return permission_denied(request)

    if request.method == 'POST':
        image.delete()
        messages.success(request,
                         _("Image '{0}' deleted.").format(image.title))
        return redirect('tuiuiuimages:index')

    return render(request, "tuiuiuimages/images/confirm_delete.html", {
        'image': image,
    })
Ejemplo n.º 13
0
    def expand_db_attributes(attrs, for_editor):
        """
        Given a dict of attributes from the <embed> tag, return the real HTML
        representation.
        """
        Image = get_image_model()
        try:
            image = Image.objects.get(id=attrs['id'])
        except Image.DoesNotExist:
            return "<img>"

        image_format = get_image_format(attrs['format'])

        if for_editor:
            return image_format.image_to_editor_html(image, attrs['alt'])
        else:
            return image_format.image_to_html(image, attrs['alt'])
Ejemplo n.º 14
0
def chooser_upload(request):
    Image = get_image_model()
    ImageForm = get_image_form(Image)

    searchform = SearchForm()

    if request.method == 'POST':
        image = Image(uploaded_by_user=request.user)
        form = ImageForm(request.POST,
                         request.FILES,
                         instance=image,
                         user=request.user)

        if form.is_valid():
            form.save()

            # Reindex the image to make sure all tags are indexed
            search_index.insert_or_update_object(image)

            if request.GET.get('select_format'):
                form = ImageInsertionForm(
                    initial={'alt_text': image.default_alt_text})
                return render_modal_workflow(
                    request, 'tuiuiuimages/chooser/select_format.html',
                    'tuiuiuimages/chooser/select_format.js', {
                        'image': image,
                        'form': form
                    })
            else:
                # not specifying a format; return the image details now
                return render_modal_workflow(
                    request, None, 'tuiuiuimages/chooser/image_chosen.js',
                    {'image_json': get_image_json(image)})
    else:
        form = ImageForm(user=request.user)

    images = Image.objects.order_by('-created_at')
    paginator, images = paginate(request, images, per_page=12)

    return render_modal_workflow(request, 'tuiuiuimages/chooser/chooser.html',
                                 'tuiuiuimages/chooser/chooser.js', {
                                     'images': images,
                                     'uploadform': form,
                                     'searchform': searchform
                                 })
Ejemplo n.º 15
0
class ServeView(View):
    model = get_image_model()
    action = 'serve'
    key = None

    @classonlymethod
    def as_view(cls, **initkwargs):
        if 'action' in initkwargs:
            if initkwargs['action'] not in ['serve', 'redirect']:
                raise ImproperlyConfigured(
                    "ServeView action must be either 'serve' or 'redirect'")

        return super(ServeView, cls).as_view(**initkwargs)

    def get(self, request, signature, image_id, filter_spec):
        if not verify_signature(
                signature.encode(), image_id, filter_spec, key=self.key):
            raise PermissionDenied

        image = get_object_or_404(self.model, id=image_id)

        # Get/generate the rendition
        try:
            rendition = image.get_rendition(filter_spec)
        except SourceImageIOError:
            return HttpResponse("Source image file not found",
                                content_type='text/plain',
                                status=410)
        except InvalidFilterSpecError:
            return HttpResponse("Invalid filter spec: " + filter_spec,
                                content_type='text/plain',
                                status=400)

        return getattr(self, self.action)(rendition)

    def serve(self, rendition):
        # Open and serve the file
        rendition.file.open('rb')
        image_format = imghdr.what(rendition.file)
        return StreamingHttpResponse(FileWrapper(rendition.file),
                                     content_type='image/' + image_format)

    def redirect(self, rendition):
        # Redirect to the file's public location
        return HttpResponsePermanentRedirect(rendition.url)
Ejemplo n.º 16
0
    def test_thumbnail(self):
        # Add a new image with source file
        image = get_image_model().objects.create(
            title="Test image",
            file=get_test_image_file(),
        )

        response = self.get_response(image.id)
        content = json.loads(response.content.decode('UTF-8'))

        self.assertIn('thumbnail', content)
        self.assertEqual(content['thumbnail']['width'], 165)
        self.assertEqual(content['thumbnail']['height'], 123)
        self.assertTrue(
            content['thumbnail']['url'].startswith('/media/images/test'))

        # Check that source_image_error didn't appear
        self.assertNotIn('source_image_error', content['meta'])
Ejemplo n.º 17
0
def url_generator(request, image_id):
    image = get_object_or_404(get_image_model(), id=image_id)

    if not permission_policy.user_has_permission_for_instance(
            request.user, 'change', image):
        return permission_denied(request)

    form = URLGeneratorForm(
        initial={
            'filter_method': 'original',
            'width': image.width,
            'height': image.height,
        })

    return render(request, "tuiuiuimages/images/url_generator.html", {
        'image': image,
        'form': form,
    })
Ejemplo n.º 18
0
def generate_url(request, image_id, filter_spec):
    # Get the image
    Image = get_image_model()
    try:
        image = Image.objects.get(id=image_id)
    except Image.DoesNotExist:
        return JsonResponse({'error': "Cannot find image."}, status=404)

    # Check if this user has edit permission on this image
    if not permission_policy.user_has_permission_for_instance(
            request.user, 'change', image):
        return JsonResponse(
            {
                'error':
                "You do not have permission to generate a URL for this image."
            },
            status=403)

    # Parse the filter spec to make sure its valid
    try:
        Filter(spec=filter_spec).operations
    except InvalidFilterSpecError:
        return JsonResponse({'error': "Invalid filter spec."}, status=400)

    # Generate url
    signature = generate_signature(image_id, filter_spec)
    url = reverse('tuiuiuimages_serve',
                  args=(signature, image_id, filter_spec))

    # Get site root url
    try:
        site_root_url = Site.objects.get(is_default_site=True).root_url
    except Site.DoesNotExist:
        site_root_url = Site.objects.first().root_url

    # Generate preview url
    preview_url = reverse('tuiuiuimages:preview', args=(image_id, filter_spec))

    return JsonResponse(
        {
            'url': site_root_url + url,
            'preview_url': preview_url
        }, status=200)
Ejemplo n.º 19
0
    def test_basic(self):
        response = self.get_response()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response['Content-type'], 'application/json')

        # Will crash if the JSON is invalid
        content = json.loads(response.content.decode('UTF-8'))

        # Check that the meta section is there
        self.assertIn('meta', content)
        self.assertIsInstance(content['meta'], dict)

        # Check that the total count is there and correct
        self.assertIn('total_count', content['meta'])
        self.assertIsInstance(content['meta']['total_count'], int)
        self.assertEqual(content['meta']['total_count'],
                         get_image_model().objects.count())

        # Check that the items section is there
        self.assertIn('items', content)
        self.assertIsInstance(content['items'], list)

        # Check that each image has a meta section with type and detail_url attributes
        for image in content['items']:
            self.assertIn('meta', image)
            self.assertIsInstance(image['meta'], dict)
            self.assertEqual(set(image['meta'].keys()),
                             {'type', 'detail_url', 'tags'})

            # Type should always be tuiuiuimages.Image
            self.assertEqual(image['meta']['type'], 'tuiuiuimages.Image')

            # Check detail url
            self.assertEqual(
                image['meta']['detail_url'],
                'http://localhost/api/v2beta/images/%d/' % image['id'])
Ejemplo n.º 20
0
def add(request):
    ImageModel = get_image_model()
    ImageForm = get_image_form(ImageModel)

    if request.method == 'POST':
        image = ImageModel(uploaded_by_user=request.user)
        form = ImageForm(request.POST,
                         request.FILES,
                         instance=image,
                         user=request.user)
        if form.is_valid():
            # Set image file size
            image.file_size = image.file.size

            form.save()

            # Reindex the image to make sure all tags are indexed
            search_index.insert_or_update_object(image)

            messages.success(request,
                             _("Image '{0}' added.").format(image.title),
                             buttons=[
                                 messages.button(
                                     reverse('tuiuiuimages:edit',
                                             args=(image.id, )), _('Edit'))
                             ])
            return redirect('tuiuiuimages:index')
        else:
            messages.error(request,
                           _("The image could not be created due to errors."))
    else:
        form = ImageForm(user=request.user)

    return render(request, "tuiuiuimages/images/add.html", {
        'form': form,
    })
Ejemplo n.º 21
0
def edit(request, image_id, callback=None):
    Image = get_image_model()
    ImageForm = get_image_edit_form(Image)

    image = get_object_or_404(Image, id=image_id)

    if not request.is_ajax():
        return HttpResponseBadRequest("Cannot POST to this view without AJAX")

    if not permission_policy.user_has_permission_for_instance(request.user, 'change', image):
        raise PermissionDenied

    form = ImageForm(
        request.POST, request.FILES, instance=image, prefix='image-' + image_id, user=request.user
    )

    if form.is_valid():
        form.save()

        # Reindex the image to make sure all tags are indexed
        for backend in get_search_backends():
            backend.add(image)

        return JsonResponse({
            'success': True,
            'image_id': int(image_id),
        })
    else:
        return JsonResponse({
            'success': False,
            'image_id': int(image_id),
            'form': render_to_string('tuiuiuimages/multiple/edit_form.html', {
                'image': image,
                'form': form,
            }, request=request),
        })
Ejemplo n.º 22
0
 def test_invalid_get_image_model(self):
     """Test get_image_model with an invalid model string"""
     with self.assertRaises(ImproperlyConfigured):
         get_image_model()
Ejemplo n.º 23
0
class ImagesAPIEndpoint(BaseAPIEndpoint):
    base_serializer_class = ImageSerializer
    filter_backends = [FieldsFilter, OrderingFilter, SearchFilter]
    extra_api_fields = ['title', 'tags', 'width', 'height']
    name = 'images'
    model = get_image_model()
Ejemplo n.º 24
0
 def test_standard_get_image_model(self):
     """Test get_image_model with no TUIUIUIMAGES_IMAGE_MODEL"""
     del settings.TUIUIUIMAGES_IMAGE_MODEL
     from tuiuiu.tuiuiuimages.models import Image
     self.assertIs(get_image_model(), Image)
Ejemplo n.º 25
0
 def test_unknown_get_image_model(self):
     """Test get_image_model with an unknown model"""
     with self.assertRaises(ImproperlyConfigured):
         get_image_model()
Ejemplo n.º 26
0
 def test_custom_get_image_model(self):
     """Test get_image_model with a custom image model"""
     self.assertIs(get_image_model(), CustomImage)
Ejemplo n.º 27
0
def chooser(request):
    Image = get_image_model()

    if permission_policy.user_has_permission(request.user, 'add'):
        ImageForm = get_image_form(Image)
        uploadform = ImageForm(user=request.user)
    else:
        uploadform = None

    images = Image.objects.order_by('-created_at')

    # allow hooks to modify the queryset
    for hook in hooks.get_hooks('construct_image_chooser_queryset'):
        images = hook(images, request)

    q = None
    if ('q' in request.GET or 'p' in request.GET or 'tag' in request.GET
            or 'collection_id' in request.GET):
        # this request is triggered from search, pagination or 'popular tags';
        # we will just render the results.html fragment
        collection_id = request.GET.get('collection_id')
        if collection_id:
            images = images.filter(collection=collection_id)

        searchform = SearchForm(request.GET)
        if searchform.is_valid():
            q = searchform.cleaned_data['q']

            images = images.search(q)
            is_searching = True
        else:
            is_searching = False

            tag_name = request.GET.get('tag')
            if tag_name:
                images = images.filter(tags__name=tag_name)

        # Pagination
        paginator, images = paginate(request, images, per_page=12)

        return render(
            request, "tuiuiuimages/chooser/results.html", {
                'images': images,
                'is_searching': is_searching,
                'query_string': q,
                'will_select_format': request.GET.get('select_format')
            })
    else:
        searchform = SearchForm()

        collections = Collection.objects.all()
        if len(collections) < 2:
            collections = None

        paginator, images = paginate(request, images, per_page=12)

        return render_modal_workflow(
            request, 'tuiuiuimages/chooser/chooser.html',
            'tuiuiuimages/chooser/chooser.js', {
                'images': images,
                'uploadform': uploadform,
                'searchform': searchform,
                'is_searching': False,
                'query_string': q,
                'will_select_format': request.GET.get('select_format'),
                'popular_tags': popular_tags_for_model(Image),
                'collections': collections,
            })
Ejemplo n.º 28
0
    def test_image_signal_handlers(self):
        image = get_image_model().objects.create(title="Test Image", file=get_test_image_file())
        image_path = image.file.path
        image.delete()

        self.assertFalse(os.path.exists(image_path))
Ejemplo n.º 29
0
from __future__ import absolute_import, unicode_literals

import PIL.Image
from django.core.files.images import ImageFile
from django.utils.six import BytesIO

from tuiuiu.tuiuiuimages import get_image_model

Image = get_image_model()


def get_test_image_file(filename='test.png', colour='white', size=(640, 480)):
    f = BytesIO()
    image = PIL.Image.new('RGB', size, colour)
    image.save(f, 'PNG')
    return ImageFile(f, name=filename)


def get_test_image_file_jpeg(filename='test.jpg',
                             colour='white',
                             size=(640, 480)):
    f = BytesIO()
    image = PIL.Image.new('RGB', size, colour)
    image.save(f, 'JPEG')
    return ImageFile(f, name=filename)
Ejemplo n.º 30
0
from __future__ import absolute_import, unicode_literals

from tuiuiu.tuiuiucore.permission_policies.collections import CollectionOwnershipPermissionPolicy
from tuiuiu.tuiuiuimages import get_image_model
from tuiuiu.tuiuiuimages.models import Image

permission_policy = CollectionOwnershipPermissionPolicy(
    get_image_model(), auth_model=Image, owner_field_name='uploaded_by_user')