def build_artifact(self, artifact):
        ctx = get_ctx()
        plugin = ctx.env.plugins["thumbnail-generator"]
        config = plugin.config

        artifact.ensure_dir()
        AttachmentBuildProgram.build_artifact(self, artifact)

        if not config:
            return

        source_img = artifact.source_obj.attachment_filename

        with open(source_img, "rb") as f:
            _, w, h = get_image_info(f)

        # For every section in the config, we need to generate one image.
        for item, conf in config.items():
            width = int(conf["max_width"])
            height = int(conf.get("max_height", "0"))

            if not height:
                _, height = compute_dimensions(width, None, w, h)

            df = artifact.source_obj.url_path
            ext_pos = df.rfind(".")
            dst_filename = "%s-%s.%s" % (df[:ext_pos], item, df[ext_pos + 1:])

            def closure(dst_filename,
                        source_img,
                        width,
                        height,
                        resize_image=True):
                # We need this closure, otherwise variables get updated and this
                # doesn't work at all.
                @ctx.sub_artifact(artifact_name=dst_filename,
                                  sources=[source_img])
                def build_thumbnail_artifact(artifact):
                    artifact.ensure_dir()
                    if not resize_image:
                        shutil.copy2(source_img, artifact.dst_filename)
                    else:
                        process_image(
                            ctx,
                            source_img,
                            artifact.dst_filename,
                            width,
                            height,
                            quality=85,
                            extra_params=[
                                "-strip",
                                "-interlace",
                                "Plane",
                            ],
                        )

            # If the image is larger than the max_width, resize it, otherwise
            # just copy it.
            resize_image = w > width or h > height
            closure(dst_filename, source_img, width, height, resize_image)
Beispiel #2
0
def test_dimensions():
    # landscape
    w, h = 100, 50
    assert compute_dimensions(50, 50, w, h) == (50, 25)
    assert compute_dimensions(100, 20, w, h) == (40, 20)
    assert compute_dimensions(200, 200, w, h) == (200, 100)
    assert compute_dimensions(500, 200, w, h) == (400, 200)
    # test missing dimension
    assert compute_dimensions(50, None, w, h) == (50, 25)
    assert compute_dimensions(None, 20, w, h) == (40, 20)
    assert compute_dimensions(200, None, w, h) == (200, 100)
    assert compute_dimensions(None, 200, w, h) == (400, 200)
    # test that rounding is half-up
    assert compute_dimensions(49, None, w, h) == (49, 25)
    assert compute_dimensions(51, None, w, h) == (51, 26)

    # portrait
    w, h = 50, 100
    assert compute_dimensions(50, 50, w, h) == (25, 50)
    assert compute_dimensions(20, 100, w, h) == (20, 40)
    assert compute_dimensions(200, 200, w, h) == (100, 200)
    assert compute_dimensions(200, 500, w, h) == (200, 400)
    #
    assert compute_dimensions(None, 50, w, h) == (25, 50)
    assert compute_dimensions(20, None, w, h) == (20, 40)
    assert compute_dimensions(None, 200, w, h) == (100, 200)
    assert compute_dimensions(200, None, w, h) == (200, 400)
    #
    assert compute_dimensions(None, 49, w, h) == (25, 49)
    assert compute_dimensions(None, 51, w, h) == (26, 51)