Exemple #1
0
class UserFloat(UserMember):

    instantiable = True
    groups_order = UserMember.groups_order
    member_class = schema.Float

    member_min = schema.Float(listed_by_default=False,
                              member_group="constraints")

    member_max = schema.Float(min=member_min,
                              listed_by_default=False,
                              member_group="constraints")
Exemple #2
0
class Sharpness(ImageEffect):

    instantiable = True

    level = schema.Float(required=True)

    def apply(self, image):
        return ImageEnhance.Sharpness(image).enhance(self.level)
Exemple #3
0
class Contrast(ImageEffect):

    instantiable = True

    level = schema.Float(required=True)

    def apply(self, image):
        return ImageEnhance.Contrast(image).enhance(self.level)
Exemple #4
0
class ReducedOpacity(ImageEffect):
    """An image effect that reduces the opacity of the given image."""

    instantiable = True

    level = schema.Float(required=True, default=0.5, min=0.0, max=1.0)

    def apply(self, image):
        return reduce_opacity(image, self.level)
Exemple #5
0
class Watermark(ImageEffect):

    instantiable = True

    mark = schema.Reference(type=File,
                            required=True,
                            related_end=schema.Collection())

    opacity = schema.Float(required=True, min=0.0, max=1.0, default=1.0)

    placement = schema.String(required=True,
                              default="middle",
                              enumeration=["middle", "scale", "tile"])

    def apply(self, image):

        mark_image = Image.open(self.mark.file_path)

        if self.opacity < 1:
            mark_image = reduce_opacity(mark_image, opacity)

        if image.mode != 'RGBA':
            image = image.convert('RGBA')

        # Create a transparent layer the size of the image and draw the
        # watermark in that layer.
        layer = Image.new('RGBA', image.size, (0, 0, 0, 0))

        if self.placement == 'tile':
            for y in range(0, image.size[1], mark_image.size[1]):
                for x in range(0, image.size[0], mark_image.size[0]):
                    layer.paste(mark_image, (x, y), mark_image)
        elif self.placement == 'scale':
            # scale, but preserve the aspect ratio
            ratio = min(
                float(image.size[0]) / mark_image.size[0],
                float(image.size[1]) / mark_image.size[1])
            w = int(mark_image.size[0] * ratio)
            h = int(mark_image.size[1] * ratio)
            mark_image = mark_image.resize((w, h))
            layer.paste(mark_image,
                        ((image.size[0] - w) / 2, (image.size[1] - h) / 2),
                        mark_image)
        elif self.placement == 'middle':
            layer.paste(mark_image, ((image.size[0] - mark_image.size[0]) / 2,
                                     (image.size[1] - mark_image.size[1]) / 2),
                        mark_image)
        else:
            raise ValueError(
                "Must specify position parameter [tile,scale,middle].")

        # composite the watermark with the layer
        return Image.composite(layer, image, layer)
Exemple #6
0
class PDFRenderer(Renderer):
    """A content renderer that handles pdf files."""

    instantiable = True

    command = schema.String(required=True)

    timeout = schema.Integer(required=True, default=20)

    timeout_size_factor = schema.Float(default=10.0)

    def can_render(self, item, **parameters):
        return (self.command and isinstance(item, File)
                and item.resource_type == "document"
                and item.file_name.split(".")[-1].lower() == "pdf")

    def render(self, item, page=1, **parameters):

        timeout = self.timeout

        # Increase the timeout for bigger files
        if self.timeout_size_factor:
            size = item.file_size
            if size:
                timeout += size / (self.timeout_size_factor * 1024 * 1024)

        RESOLUTION = 0.25
        temp_path = mkdtemp()

        try:
            temp_image_file = os.path.join(temp_path, "thumbnail.png")

            command = self.command % {
                "source": item.file_path,
                "dest": temp_image_file,
                "page": page
            }

            p = Popen(command, shell=True, stdout=PIPE)
            start = time()

            while p.poll() is None:
                if time() - start > timeout:
                    p.terminate()
                    raise IOError("PDF rendering timeout: '%s' took more than "
                                  "%.2f seconds" % (command, timeout))
                sleep(RESOLUTION)

            return Image.open(temp_image_file)

        finally:
            rmtree(temp_path)
Exemple #7
0
class AudioEncoder(Item):

    instantiable = True
    visible_from_root = False
    resolution = 0.25

    members_order = [
        "identifier", "mime_type", "extension", "command", "timeout",
        "timeout_size_factor"
    ]

    identifier = schema.String(required=True,
                               unique=True,
                               indexed=True,
                               normalized_index=False,
                               descriptive=True)

    mime_type = schema.String(required=True)

    extension = schema.String(required=True)

    command = schema.String(required=True)

    timeout = schema.Integer(required=True, default=60)

    timeout_size_factor = schema.Float(default=10.0)

    def encode(self, file, dest):

        # Most encoders expect PCM wave files as input, so we start by finding
        # an appropiate decoder for the given file.
        mime_type = file.mime_type

        if mime_type == "audio/mp3":
            mime_type = "audio/mpeg"

        decoder = AudioDecoder.require_instance(mime_type=mime_type)

        # Next, we produce the command line instructions for the decoding /
        # encoding procedure, using a shell pipe.
        decode_command = decoder.command % file.file_path
        encode_command = self.command % dest
        command = decode_command + " | " + encode_command

        # Calculate the timeout, based on a base value incremented according to
        # a file size factor
        timeout = self.timeout

        if self.timeout_size_factor:
            size = file.file_size
            if size:
                timeout += size / (self.timeout_size_factor * 1024 * 1024)

        # Encode the file and save it to the indicated location
        proc = Popen(command, shell=True, stdout=PIPE, stderr=PIPE)
        start = time()

        while proc.poll() is None:
            if time() - start > timeout:
                proc.terminate()
                raise AudioEncodingTimeoutError(
                    "The following audio encoding command exceeded its "
                    "timeout of %d seconds: %s" % (timeout, command))
            sleep(self.resolution)

        if proc.returncode:
            raise AudioEncodingCommandError(
                "The following audio encoding command reported an error: "
                "%s\n%s" % (command, proc.stderr.read().strip()))