Пример #1
0
    def test_prefetch_related_through_table(self):
        author = Author.objects.create(name="Author")
        for x in range(10):
            article = Article.objects.create(
                title="prefetch",
                author=author,
                lead_image=self.create_unique_image('img.jpg'),
                alt_image=self.create_unique_image('img.png'))
            article.lead_image.generate_thumbs()
            article.alt_image.generate_thumbs()

        lead_sizes = [s.name for s in Size.flatten(Article.LEAD_IMAGE_SIZES)]
        alt_sizes = [s.name for s in Size.flatten(Article.ALT_IMAGE_SIZES)]

        with self.assertNumQueries(6):
            authors = Author.objects.filter(pk=author.pk).prefetch_related(
                'article_set__lead_image__thumbs',
                'article_set__alt_image__thumbs')
            for author in authors:
                for article in author.article_set.all():
                    self.assertTrue(article.lead_image.name.endswith('jpg'))
                    self.assertTrue(article.alt_image.name.endswith('png'))
                    for thumb in article.lead_image.related_object.thumbs.all(
                    ):
                        self.assertIn(thumb.name, lead_sizes)
                    for thumb in article.alt_image.related_object.thumbs.all():
                        self.assertIn(thumb.name, alt_sizes)
Пример #2
0
    def test_prefetch_related_through_table(self):
        author = Author.objects.create(name="Author")
        for x in range(10):
            article = Article.objects.create(
                title="prefetch", author=author,
                lead_image=self.create_unique_image('img.jpg'),
                alt_image=self.create_unique_image('img.png'))
            article.lead_image.generate_thumbs()
            article.alt_image.generate_thumbs()

        lead_sizes = [s.name for s in Size.flatten(Article.LEAD_IMAGE_SIZES)]
        alt_sizes = [s.name for s in Size.flatten(Article.ALT_IMAGE_SIZES)]

        with self.assertNumQueries(6):
            authors = Author.objects.filter(pk=author.pk).prefetch_related(
                'article_set__lead_image__thumbs',
                'article_set__alt_image__thumbs')
            for author in authors:
                for article in author.article_set.all():
                    self.assertTrue(article.lead_image.path.endswith('jpg'))
                    self.assertTrue(article.alt_image.path.endswith('png'))
                    for thumb in article.lead_image.related_object.thumbs.all():
                        self.assertIn(thumb.name, lead_sizes)
                    for thumb in article.alt_image.related_object.thumbs.all():
                        self.assertIn(thumb.name, alt_sizes)
Пример #3
0
 def sizes(self):
     size = getattr(self.image_file.metadata, 'crop_size', None)
     if not size:
         size = Size('crop', max_w=self.max_w)
     else:
         size.max_w = self.max_w
     return [size]
Пример #4
0
    def test_prefetch_related_with_alt_images(self):
        img_map = {}
        for x in range(3):
            lead_image_path = self.create_unique_image('img.jpg')
            alt_image_path = self.create_unique_image('img.jpg')
            article = Article.objects.create(title="", author=self.author,
                lead_image=lead_image_path, alt_image=alt_image_path)
            article.lead_image.generate_thumbs()
            article.alt_image.generate_thumbs()
            img_map[article.pk] = (lead_image_path, alt_image_path)

        with self.assertNumQueries(5):
            articles = (Article.objects.filter(id__in=img_map.keys())
                .prefetch_related('lead_image__thumbs', 'alt_image__thumbs'))
            for article in articles:
                lead_name, alt_name = img_map[article.pk]
                self.assertEqual(lead_name, article.lead_image.related_object.image.name)
                self.assertEqual(alt_name, article.alt_image.related_object.image.name)

                lead_sizes = [s.name for s in Size.flatten(Article.LEAD_IMAGE_SIZES)]
                lead_thumbs = list(article.lead_image.related_object.thumbs.all())
                self.assertEqual(len(lead_thumbs), len(lead_sizes))
                for thumb in lead_thumbs:
                    self.assertEqual(thumb.image_id, article.lead_image.related_object.pk)
                    self.assertIn(thumb.name, lead_sizes)

                alt_sizes = [s.name for s in Size.flatten(Article.ALT_IMAGE_SIZES)]
                alt_thumbs = list(article.alt_image.related_object.thumbs.all())
                self.assertEqual(len(alt_thumbs), len(alt_sizes))
                for thumb in alt_thumbs:
                    self.assertEqual(thumb.image_id, article.alt_image.related_object.pk)
                    self.assertIn(thumb.name, alt_sizes)
Пример #5
0
class Author(models.Model):
    name = models.CharField(max_length=255)
    HEADSHOT_SIZES = [
        Size('main', w=220, h=180, auto=[
            Size('thumb', w=110, h=90),
        ]),
    ]
    headshot = CropDusterField(upload_to="author/headshots/%Y/%m",
                               sizes=HEADSHOT_SIZES,
                               related_name="author_headshotset")
Пример #6
0
    def test_addform_multiple_image(self):
        author = Author.objects.create(name="Mark Twain")
        self.load_admin(Article)
        browser = self.selenium
        browser.find_element_by_id('id_title').send_keys(
            "A Connecticut Yankee in King Arthur's Court")

        # Upload and crop first Image
        browser.find_element_by_css_selector(
            '#lead_image-group .cropduster-button').click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.jpg'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()
            with self.clickable_selector('#crop-button:not(.disabled)') as el:
                el.click()

        # Upload and crop second Image
        with self.clickable_selector(
                '#alt_image-group .cropduster-button') as el:
            # With the Chrome driver, using Grappelli, this button can be covered
            # by the fixed footer. So we scroll the button into view.
            browser.execute_script('window.scrollTo(0, %d)' % el.location['y'])
            el.click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.png'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()

        # Add required FK
        browser.find_element_by_xpath(
            '//select[@id="id_author"]/option[@value=%d]' % author.pk).click()

        self.save_form()

        # Test that crops saved correctly
        article = Article.objects.all()[0]
        lead_sizes = list(Size.flatten(Article.LEAD_IMAGE_SIZES))
        alt_sizes = list(Size.flatten(Article.ALT_IMAGE_SIZES))

        self.assertTrue(article.lead_image.name.endswith('.jpg'))
        self.assertEqual(len(article.lead_image.related_object.thumbs.all()),
                         len(lead_sizes))
        self.assertTrue(article.alt_image.name.endswith('.png'))
        self.assertEqual(len(article.alt_image.related_object.thumbs.all()),
                         len(alt_sizes))
Пример #7
0
class OptionalSizes(models.Model):

    TEST_SIZES = [
        Size('main',
             w=600,
             h=480,
             auto=[
                 Size('optional', w=1200, h=960, required=False),
             ])
    ]

    slug = models.SlugField()
    image = CropDusterField(upload_to="test", sizes=TEST_SIZES)
Пример #8
0
    def test_addform_multiple_image(self):
        author = Author.objects.create(name="Mark Twain")
        self.load_admin(Article)
        browser = self.selenium
        browser.find_element_by_id('id_title').send_keys("A Connecticut Yankee in King Arthur's Court")

        # Upload and crop first Image
        browser.find_element_by_css_selector('#lead_image-group .cropduster-button').click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.jpg'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()
            with self.clickable_selector('#crop-button:not(.disabled)') as el:
                el.click()

        # Upload and crop second Image
        with self.clickable_selector('#alt_image-group .cropduster-button') as el:
            # With the Chrome driver, using Grappelli, this button can be covered
            # by the fixed footer. So we scroll the button into view.
            browser.execute_script('window.scrollTo(0, %d)' % el.location['y'])
            el.click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.png'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()

        # Add required FK
        browser.find_element_by_xpath('//select[@id="id_author"]/option[@value=%d]' % author.pk).click()

        self.save_form()

        # Test that crops saved correctly
        article = Article.objects.all()[0]
        lead_sizes = list(Size.flatten(Article.LEAD_IMAGE_SIZES))
        alt_sizes = list(Size.flatten(Article.ALT_IMAGE_SIZES))

        self.assertTrue(article.lead_image.path.endswith('.jpg'))
        self.assertEqual(len(article.lead_image.related_object.thumbs.all()), len(lead_sizes))
        self.assertTrue(article.alt_image.path.endswith('.png'))
        self.assertEqual(len(article.alt_image.related_object.thumbs.all()), len(alt_sizes))
Пример #9
0
 def test_dont_generate_thumbs(self):
     article = Article.objects.create(
         title="Pudd'nhead Wilson",
         author=self.author,
         lead_image=self.create_unique_image('img.jpg'))
     article.lead_image.generate_thumbs()
     article = Article.objects.get(pk=article.pk)
     sizes = sorted(list(Size.flatten(Article.LEAD_IMAGE_SIZES)),
                    key=lambda x: x.name)
     thumbs = sorted(list(article.lead_image.related_object.thumbs.all()),
                     key=lambda x: x.name)
     self.assertEqual(len(thumbs), len(sizes))
     for size, thumb in zip(sizes, thumbs):
         self.assertEqual(size.name, thumb.name)
         if size.width:
             self.assertEqual(size.width, thumb.width)
         if size.height:
             self.assertEqual(size.height, thumb.height)
         else:
             ratio = article.lead_image.height / article.lead_image.width
             self.assertAlmostEqual(thumb.height,
                                    ratio * size.width,
                                    delta=1)
         self.assertEqual(thumb.image.image,
                          article.lead_image.related_object.image)
         self.assertFalse(default_storage.exists(thumb.image_name))
         with self.assertRaises(IOError):
             default_storage.open(thumb.image_name, mode='rb')
Пример #10
0
    def test_generate_thumbs(self):
        article = Article.objects.create(title="Pudd'nhead Wilson",
            author=self.author, lead_image=self.create_unique_image('img.jpg'))
        article.lead_image.generate_thumbs()
        article = Article.objects.get(pk=article.pk)
        sizes = sorted(list(Size.flatten(Article.LEAD_IMAGE_SIZES)), key=lambda x: x.name)
        thumbs = sorted(list(article.lead_image.related_object.thumbs.all()), key=lambda x: x.name)
        self.assertEqual(len(thumbs), len(sizes))
        for size, thumb in zip(sizes, thumbs):
            self.assertEqual(size.name, thumb.name)
            if size.width:
                self.assertEqual(size.width, thumb.width)
            if size.height:
                self.assertEqual(size.height, thumb.height)
            else:
                ratio = article.lead_image.height / article.lead_image.width
                self.assertAlmostEqual(thumb.height, ratio * size.width, delta=1)
            self.assertEqual(thumb.image.image, article.lead_image.related_object.image)
            self.assertTrue(os.path.exists(thumb.path))
            self.assertEqual((thumb.width, thumb.height), PIL.Image.open(thumb.path).size)

        image = PIL.Image.open(os.path.join(self.TEST_IMG_DIR, 'img.jpg'))
        image.thumbnail((50, 50))
        image.save(os.path.join(self.TEST_IMG_DIR, 'new-img.jpg'))
        new_image_path = self.create_unique_image('new-img.jpg')
        article = Article.objects.create(
            title="Img Too Small", author=self.author, lead_image=new_image_path)
        self.assertRaises(CropDusterResizeException, article.lead_image.generate_thumbs)
Пример #11
0
class OrphanedThumbs(models.Model):

    TEST_SIZES = [
        Size('main', w=600, h=480, auto=[
            Size('main@2x', w=1200, h=960),
        ]),
        Size('secondary',
             w=600,
             h=480,
             auto=[
                 Size('secondary@2x', w=1200, h=960),
             ])
    ]

    slug = models.SlugField()
    image = CropDusterField(upload_to="test", sizes=TEST_SIZES)
Пример #12
0
    def test_prefetch_related_with_alt_images(self):
        img_map = {}
        for x in range(3):
            lead_image_path = self.create_unique_image('img.jpg')
            alt_image_path = self.create_unique_image('img.jpg')
            article = Article.objects.create(title="",
                                             author=self.author,
                                             lead_image=lead_image_path,
                                             alt_image=alt_image_path)
            article.lead_image.generate_thumbs()
            article.alt_image.generate_thumbs()
            img_map[article.pk] = (lead_image_path, alt_image_path)

        with self.assertNumQueries(5):
            articles = (Article.objects.filter(
                id__in=img_map.keys()).prefetch_related(
                    'lead_image__thumbs', 'alt_image__thumbs'))
            for article in articles:
                lead_name, alt_name = img_map[article.pk]
                self.assertEqual(lead_name,
                                 article.lead_image.related_object.image.name)
                self.assertEqual(alt_name,
                                 article.alt_image.related_object.image.name)

                lead_sizes = [
                    s.name for s in Size.flatten(Article.LEAD_IMAGE_SIZES)
                ]
                lead_thumbs = list(
                    article.lead_image.related_object.thumbs.all())
                self.assertEqual(len(lead_thumbs), len(lead_sizes))
                for thumb in lead_thumbs:
                    self.assertEqual(thumb.image_id,
                                     article.lead_image.related_object.pk)
                    self.assertIn(thumb.name, lead_sizes)

                alt_sizes = [
                    s.name for s in Size.flatten(Article.ALT_IMAGE_SIZES)
                ]
                alt_thumbs = list(
                    article.alt_image.related_object.thumbs.all())
                self.assertEqual(len(alt_thumbs), len(alt_sizes))
                for thumb in alt_thumbs:
                    self.assertEqual(thumb.image_id,
                                     article.alt_image.related_object.pk)
                    self.assertIn(thumb.name, alt_sizes)
Пример #13
0
    def test_addform_single_image(self):
        self.load_admin(Author)

        browser = self.selenium
        browser.find_element_by_id('id_name').send_keys('Mark Twain')
        with self.clickable_selector(
                '#headshot-group .cropduster-button') as el:
            el.click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.png'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()

        self.save_form()

        author = Author.objects.all()[0]
        sizes = list(Size.flatten(Author.HEADSHOT_SIZES))
        self.assertTrue(bool(author.headshot.name))

        image = author.headshot.related_object
        thumbs = image.thumbs.all()
        self.assertEqual(len(thumbs), len(sizes))
        main_thumb = image.thumbs.get(name='main')
        self.assertEqual(
            main_thumb.to_dict(), {
                'reference_thumb_id': None,
                'name': 'main',
                'width': 220,
                'height': 180,
                'crop_w': 674,
                'crop_h': 551,
                'crop_x': 0,
                'crop_y': 125,
                'image_id': image.pk,
                'id': main_thumb.pk,
            })
        auto_thumb = image.thumbs.get(name='thumb')
        self.assertEqual(
            auto_thumb.to_dict(), {
                'reference_thumb_id': main_thumb.pk,
                'name': 'thumb',
                'width': 110,
                'height': 90,
                'crop_w': None,
                'crop_h': None,
                'crop_x': None,
                'crop_y': None,
                'image_id': image.pk,
                'id': auto_thumb.pk,
            })
        self.assertTrue(default_storage.exists(auto_thumb.image_name))
Пример #14
0
    def test_addform_single_image(self):
        self.load_admin(Author)

        browser = self.selenium
        browser.find_element_by_id('id_name').send_keys('Mark Twain')
        with self.clickable_selector('#headshot-group .cropduster-button') as el:
            el.click()

        with self.switch_to_popup_window():
            with self.visible_selector('#id_image') as el:
                el.send_keys(os.path.join(self.TEST_IMG_DIR, 'img.jpg'))
            with self.clickable_selector('#upload-button') as el:
                el.click()
            with self.clickable_selector('#crop-button') as el:
                el.click()

        self.save_form()

        author = Author.objects.all()[0]
        sizes = list(Size.flatten(Author.HEADSHOT_SIZES))
        self.assertTrue(bool(author.headshot.path))

        image = author.headshot.related_object
        thumbs = image.thumbs.all()
        self.assertEqual(len(thumbs), len(sizes))
        main_thumb = image.thumbs.get(name='main')
        self.assertEqual(main_thumb.to_dict(), {
            'reference_thumb_id': None,
            'name': 'main',
            'width': 220,
            'height': 180,
            'crop_w': 674,
            'crop_h': 551,
            'crop_x': 0,
            'crop_y': 125,
            'image_id': image.pk,
            'id': main_thumb.pk,
        })
        auto_thumb = image.thumbs.get(name='thumb')
        self.assertEqual(auto_thumb.to_dict(), {
            'reference_thumb_id': main_thumb.pk,
            'name': 'thumb',
            'width': 110,
            'height': 90,
            'crop_w': None,
            'crop_h': None,
            'crop_x': None,
            'crop_y': None,
            'image_id': image.pk,
            'id': auto_thumb.pk,
        })
        self.assertTrue(os.path.exists(auto_thumb.path))
Пример #15
0
class Article(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(to=Author,
                               blank=True,
                               null=True,
                               on_delete=models.SET_NULL)
    LEAD_IMAGE_SIZES = [
        Size(u'main', w=600, h=480, auto=[
            Size(u'thumb', w=110, h=90),
        ]),
        Size(u'no_height', w=600),
    ]
    ALT_IMAGE_SIZES = [
        Size(u'wide', w=600, h=300),
    ]
    lead_image = CropDusterField(upload_to="article/lead_image/%Y/%m",
                                 db_column='image',
                                 related_name="test_article_lead_image",
                                 sizes=LEAD_IMAGE_SIZES)
    alt_image = CropDusterField(upload_to="article/alt_image/%Y/%m",
                                related_name="test_article_alt_image",
                                sizes=ALT_IMAGE_SIZES,
                                field_identifier="alt")
Пример #16
0
    def test_generate_thumbs(self):
        article = Article.objects.create(
            title="Pudd'nhead Wilson",
            author=self.author,
            lead_image=self.create_unique_image('img.jpg'))
        article.lead_image.generate_thumbs()
        article = Article.objects.get(pk=article.pk)
        sizes = sorted(list(Size.flatten(Article.LEAD_IMAGE_SIZES)),
                       key=lambda x: x.name)
        thumbs = sorted(list(article.lead_image.related_object.thumbs.all()),
                        key=lambda x: x.name)
        self.assertEqual(len(thumbs), len(sizes))
        for size, thumb in zip(sizes, thumbs):
            self.assertEqual(size.name, thumb.name)
            if size.width:
                self.assertEqual(size.width, thumb.width)
            if size.height:
                self.assertEqual(size.height, thumb.height)
            else:
                ratio = article.lead_image.height / article.lead_image.width
                self.assertAlmostEqual(thumb.height,
                                       ratio * size.width,
                                       delta=1)
            self.assertEqual(thumb.image.image,
                             article.lead_image.related_object.image)
            self.assertTrue(default_storage.exists(thumb.image_name))
            with default_storage.open(thumb.image_name, mode='rb') as f:
                self.assertEqual((thumb.width, thumb.height),
                                 PIL.Image.open(f).size)

        image = PIL.Image.open(os.path.join(self.TEST_IMG_DIR, 'img.jpg'))
        image.thumbnail((50, 50))
        buf = BytesIO()
        image.save(buf, format=image.format)
        default_storage.save('new-img.jpg', buf)
        article = Article.objects.create(title="Img Too Small",
                                         author=self.author,
                                         lead_image='new-img.jpg')
        self.assertRaises(CropDusterResizeException,
                          article.lead_image.generate_thumbs)
Пример #17
0
class MultipleFieldsInheritanceChild(MultipleFieldsInheritanceParent):

    image2 = CropDusterField(upload_to="test",
                             sizes=[Size(u'main', w=600, h=480)],
                             field_identifier="2")
Пример #18
0
class MultipleFieldsInheritanceParent(models.Model):

    slug = models.SlugField()
    image = CropDusterField(upload_to="test",
                            sizes=[Size(u'main', w=600, h=480)])
Пример #19
0
def upload(request):
    if request.method == 'GET':
        return index(request)

    # The data we'll be returning as JSON
    data = {
        'warning': [],
    }

    form = UploadForm(request.POST, request.FILES)

    if not form.is_valid():
        errors = form['image'].errors or form.errors
        return json_error(request,
                          'upload',
                          action="uploading file",
                          errors=[force_text(errors)])

    form_data = form.cleaned_data
    is_standalone = bool(form_data.get('standalone'))

    orig_file_path = form_data['image'].name
    if six.PY2 and isinstance(orig_file_path, six.text_type):
        orig_file_path = orig_file_path.encode('utf-8')
    orig_image = get_relative_media_url(orig_file_path)

    with default_storage.open(orig_image, mode='rb') as f:
        img = PIL.Image.open(BytesIO(f.read()))
        img.filename = f.name

    (w, h) = (orig_w, orig_h) = img.size

    if is_animated_gif(img) and not has_animated_gif_support():
        data['warning'].append(
            u"This server does not have animated gif support; your uploaded image "
            u"has been made static.")

    tmp_image = Image(image=orig_image)
    preview_w = form_data.get('preview_width') or PREVIEW_WIDTH
    preview_h = form_data.get('preview_height') or PREVIEW_HEIGHT

    # First pass resize if it's too large
    resize_ratio = min(preview_w / w, preview_h / h)

    def fit_preview(im):
        (w, h) = im.size
        if resize_ratio < 1:
            w = int(round(w * resize_ratio))
            h = int(round(h * resize_ratio))
            preview_img = im.resize((w, h), PIL.Image.ANTIALIAS)
        else:
            preview_img = im
        return preview_img

    if not is_standalone:
        preview_file_path = tmp_image.get_image_path('_preview')
        process_image(img, preview_file_path, fit_preview)

    data.update({
        'crop': {
            'orig_image': orig_image,
            'orig_w': orig_w,
            'orig_h': orig_h,
            'image_id': None,
        },
        'url': tmp_image.get_image_url('_preview'),
        'orig_image': orig_image,
        'orig_w': orig_w,
        'orig_h': orig_h,
        'width': w,
        'height': h,
    })
    if not is_standalone:
        return HttpResponse(json.dumps(data), content_type='application/json')

    size = Size('crop', w=img.size[0], h=img.size[1])

    md5 = form_data.get('md5')
    try:
        standalone_image = StandaloneImage.objects.get(md5=md5)
    except StandaloneImage.DoesNotExist:
        standalone_image = StandaloneImage(md5=md5, image=orig_image)
        standalone_image.save()
    cropduster_image, created = Image.objects.get_or_create(
        content_type=ContentType.objects.get_for_model(StandaloneImage),
        object_id=standalone_image.pk)

    if not cropduster_image.image:
        cropduster_image.image = orig_image
        cropduster_image.save()
    elif cropduster_image.image.name != orig_image:
        data['crop']['orig_image'] = data[
            'orig_image'] = cropduster_image.image.name
        data['url'] = cropduster_image.get_image_url('_preview')

    with cropduster_image.image as f:
        f.open()
        img = PIL.Image.open(BytesIO(f.read()))
        img.filename = f.name
    preview_file_path = cropduster_image.get_image_path('_preview')
    if not default_storage.exists(preview_file_path):
        process_image(img, preview_file_path, fit_preview)

    thumb = cropduster_image.save_size(size, standalone=True, commit=False)

    sizes = form_data.get('sizes') or []
    if len(sizes) == 1:
        size = sizes[0]
    else:
        size = Size('crop')

    data.update({
        'thumbs': [{
            'crop_x': thumb.crop_x,
            'crop_y': thumb.crop_y,
            'crop_w': thumb.crop_w,
            'crop_h': thumb.crop_h,
            'width': thumb.width,
            'height': thumb.height,
            'id': None,
            'changed': True,
            'size': json.dumps(size),
            'name': thumb.name,
        }]
    })
    data['crop'].update({
        'image_id': cropduster_image.pk,
        'sizes': json.dumps([size]),
    })
    return HttpResponse(json.dumps(data), content_type='application/json')
Пример #20
0
def upload(request):

    size_set = SizeSet.objects.get(id=request.GET["size_set"])

    # Get the current aspect ratio
    if "aspect_ratio_id" in request.POST:
        aspect_ratio_id = int(request.POST["aspect_ratio_id"])
    else:
        aspect_ratio_id = 0

    image_id = None

    if "image_id" in request.GET:
        image_id = request.GET["image_id"]
    elif "image_id" in request.POST:
        image_id = request.POST["image_id"]

    try:
        image_id = int(image_id)
        image = CropDusterImage.objects.get(id=image_id)
    except:
        image = CropDusterImage(size_set=size_set)

    size = Size.objects.get_size_by_ratio(size_set.id,
                                          aspect_ratio_id) or Size()

    # Get the current crop
    try:
        crop = Crop.objects.get(image=image.id, size=size.id)
    except Crop.DoesNotExist:
        crop = Crop()
        crop.crop_w = size.width
        crop.crop_h = size.height
        crop.crop_x = 0
        crop.crop_y = 0
        crop.image = image
        crop.size = size

    if request.method == "POST":
        if request.FILES:

            # Process uploaded image form
            formset = ImageForm(request.POST, request.FILES, instance=image)

            if formset.is_valid():

                if CROPDUSTER_EXIF_DATA:
                    # Check for exif data and use it to populate caption/attribution
                    try:
                        exif_data = process_file(
                            io.BytesIO(
                                b"%s" %
                                formset.cleaned_data["image"].file.getvalue()))
                    except AttributeError:
                        exif_data = {}

                    if not formset.cleaned_data[
                            "caption"] and "Image ImageDescription" in exif_data:
                        formset.data["caption"] = exif_data[
                            "Image ImageDescription"].__str__()
                    if not formset.cleaned_data[
                            "attribution"] and "EXIF UserComment" in exif_data:
                        formset.data["attribution"] = exif_data[
                            "EXIF UserComment"].__str__()

                image = formset.save()
                crop.image = image
                crop_formset = CropForm(instance=crop)
            else:
                # Invalid upload return form
                errors = formset.errors.values()[0]
                context = {
                    "aspect_ratio_id": 0,
                    "errors": errors,
                    "formset": formset,
                    "image_element_id": request.GET["image_element_id"],
                    "static_url": settings.STATIC_URL,
                }

                context = RequestContext(request, context)

                return render_to_response("admin/upload.html", context)

        else:

            #If its the first frame, get the image formset and save it (for attribution)

            if not aspect_ratio_id:
                formset = ImageForm(request.POST, instance=image)
                if formset.is_valid():
                    formset.save()
            else:
                formset = ImageForm(instance=image)

            # If there's no cropping to be done, then just complete the process
            if size.id:

                # Lets save the crop
                request.POST['size'] = size.id
                request.POST['image'] = image.id
                crop_formset = CropForm(request.POST, instance=crop)

                if crop_formset.is_valid():
                    crop = crop_formset.save()

                    #Now get the next crop if it exists
                    aspect_ratio_id = aspect_ratio_id + 1
                    size = Size.objects.get_size_by_ratio(
                        size_set, aspect_ratio_id)

                    # If there's another crop
                    if size:
                        try:
                            crop = Crop.objects.get(image=image.id,
                                                    size=size.id)
                            crop_formset = CropForm(instance=crop)
                        except Crop.DoesNotExist:
                            crop = Crop()
                            crop.crop_w = size.width
                            crop.crop_h = size.height
                            crop.crop_x = 0
                            crop.crop_y = 0
                            crop.size = size
                            crop_formset = CropForm()

    # Nothing being posted, get the image and form if they exist
    else:
        formset = ImageForm(instance=image)
        crop_formset = CropForm(instance=crop)

    # If theres more cropping to be done or its the first frame,
    # show the upload/crop form
    if (size and size.id) or request.method != "POST":

        crop_w = crop.crop_w or size.width
        crop_h = crop.crop_h or size.height

        # Combine errors from both forms, eliminate duplicates
        errors = dict(crop_formset.errors)
        errors.update(formset.errors)
        all_errors = []
        for error in errors.items():
            if error[0] != '__all__':
                string = u"%s: %s" % (error[0].capitalize(),
                                      error[1].as_text())
            else:
                string = error[1].as_text()
            all_errors.append(string)

        context = {
            "aspect_ratio": size.aspect_ratio,
            "aspect_ratio_id": aspect_ratio_id,
            "browser_width": BROWSER_WIDTH,
            "crop_formset": crop_formset,
            "crop_w": crop_w,
            "crop_h": crop_h,
            "crop_x": crop.crop_x or 0,
            "crop_y": crop.crop_y or 0,
            "errors": all_errors,
            "formset": formset,
            "image": image,
            "image_element_id": request.GET["image_element_id"],
            "image_exists": image.image and os.path.exists(image.image.path),
            "min_w": size.width,
            "min_h": size.height,
            "static_url": settings.STATIC_URL,
        }

        context = RequestContext(request, context)

        return render_to_response("admin/upload.html", context)

    # No more cropping to be done, close out
    else:
        image_thumbs = [
            image.thumbnail_url(size.slug)
            for size in image.size_set.get_unique_ratios()
        ]

        context = {
            "image": image,
            "image_thumbs": image_thumbs,
            "image_element_id": request.GET["image_element_id"],
            "static_url": settings.STATIC_URL,
        }

        context = RequestContext(request, context)
        return render_to_response("admin/complete.html", context)