Пример #1
0
    def thumb(self, image, **kwargs):
        url = image.url

        if not url:
            return None

        if settings.THUMBOR_BASE_URL:
            # If THUMBOR_BASE_URL is explicity set, use that
            base = settings.THUMBOR_BASE_URL
        else:
            # otherwise assume that thumbor is setup behind the same
            # CDN behind the `thumbor` namespace.
            scheme, netloc = urlparse.urlsplit(url)[:2]
            base = '{}://{}/thumbor'.format(scheme, netloc)
        crypto = CryptoURL(key=settings.THUMBOR_KEY)

        # just for code clarity
        thumbor_kwargs = kwargs
        if not 'fit_in' in thumbor_kwargs:
            thumbor_kwargs['fit_in'] = False

        thumbor_kwargs['image_url'] = url

        path = crypto.generate(**thumbor_kwargs)
        return u'{}{}'.format(base, path)
Пример #2
0
    def test_image_already_generated_by_thumbor_2_times(self):
        with open(
            normalize_unicode_path(u'./tests/fixtures/images/alabama1_ap620é.jpg'), 'r'
        ) as f:
            self.context.modules.storage.put(
                quote("http://test.com/smart/alabama1_ap620é"),
                f.read()
            )
        crypto = CryptoURL('ACME-SEC')
        image_url = self.get_url(
            crypto.generate(
                image_url=quote(self.get_url(
                    crypto.generate(
                        image_url=quote("http://test.com/smart/alabama1_ap620é")
                    )
                ))
            )
        )

        url = crypto.generate(
            image_url=quote(image_url)
        )

        response = self.fetch(url)
        expect(response.code).to_equal(200)
Пример #3
0
def test_usage_new_format():
    key = "my-security-key"
    image = "s.glbimg.com/et/bb/f/original/2011/03/24/VN0JiwzmOw0b0lg.jpg"

    thumbor_signer = Signer(key)
    thumbor_url = Url.generate_options(
        width=300,
        height=200,
        smart=True,
        adaptive=False,
        fit_in=False,
        horizontal_flip=False,
        vertical_flip=False,
        crop_left=0,
        crop_top=0,
        crop_right=0,
        crop_bottom=0,
        filters=[],
    )
    thumbor_url = (f"{thumbor_url}/{image}").lstrip("/")
    signature = thumbor_signer.signature(thumbor_url).decode("ascii")
    thumbor_url = f"/{signature}/{thumbor_url}"

    crypto = CryptoURL(key=key)
    url = crypto.generate(width=300, height=200, smart=True, image_url=image)

    assert url == thumbor_url
Пример #4
0
def main(arguments=None):
    '''Converts a given url with the specified arguments.'''

    parsed_options, arguments = get_options(arguments)

    image_url = arguments[0]
    image_url = quote(image_url)

    try:
        config = Config.load(None)
    except:
        config = None

    if not parsed_options.key and not config:
        sys.stdout.write(
            'Error: The -k or --key argument is mandatory. For more information type thumbor-url -h\n'
        )
        return

    security_key, thumbor_params = get_thumbor_params(image_url,
                                                      parsed_options, config)

    crypto = CryptoURL(key=security_key)
    url = crypto.generate(**thumbor_params)
    sys.stdout.write('URL:\n')
    sys.stdout.write('%s\n' % url)

    return url
Пример #5
0
def test_usage():
    key = "my-security-key"
    image = "s.glbimg.com/et/bb/f/original/2011/03/24/VN0JiwzmOw0b0lg.jpg"
    thumbor_crypto = Cryptor(key)

    thumbor_options = thumbor_crypto.encrypt(width=300,
                                             height=200,
                                             smart=True,
                                             adaptive=False,
                                             full=False,
                                             fit_in=False,
                                             flip_horizontal=False,
                                             flip_vertical=False,
                                             halign='center',
                                             valign='middle',
                                             trim=None,
                                             crop_left=0,
                                             crop_top=0,
                                             crop_right=0,
                                             crop_bottom=0,
                                             filters=[],
                                             image=image)
    thumbor_url = "/%s/%s" % (thumbor_options, image)

    crypto = CryptoURL(key=key)

    url = crypto.generate(width=300,
                          height=200,
                          smart=True,
                          image_url=image,
                          old=True)

    assert url == thumbor_url
Пример #6
0
def test_usage():
    key = "my-security-key"
    image = "s.glbimg.com/et/bb/f/original/2011/03/24/VN0JiwzmOw0b0lg.jpg"
    thumbor_crypto = Crypto(salt=key)

    thumbor_options = thumbor_crypto.encrypt(
        300,
        200,
        True,
        False,
        False,
        'center',
        'middle',
        0, 0, 0, 0,
        image=image
    )
    thumbor_url = "/%s/%s" % (thumbor_options, image)

    crypto = CryptoURL(key=key)

    url = crypto.generate(
        width=300,
        height=200,
        smart=True,
        image_url=image
    )

    assert url == thumbor_url
Пример #7
0
def test_usage_new_format():
    key = "my-security-key"
    image = "s.glbimg.com/et/bb/f/original/2011/03/24/VN0JiwzmOw0b0lg.jpg"

    thumbor_signer = Signer(key)
    thumbor_url = Url.generate_options(width=300,
                                       height=200,
                                       smart=True,
                                       adaptive=False,
                                       fit_in=False,
                                       horizontal_flip=False,
                                       vertical_flip=False,
                                       halign='center',
                                       valign='middle',
                                       crop_left=0,
                                       crop_top=0,
                                       crop_right=0,
                                       crop_bottom=0,
                                       filters=[])
    thumbor_url = ('%s/%s' % (thumbor_url, image)).lstrip('/')
    thumbor_url = '/%s/%s' % (thumbor_signer.signature(thumbor_url),
                              thumbor_url)

    crypto = CryptoURL(key=key)
    url = crypto.generate(width=300, height=200, smart=True, image_url=image)

    assert url == thumbor_url
Пример #8
0
def generate_thumbnail_url(path: str, size: str = '0x0') -> str:
    if not (path.startswith('https://') or path.startswith('http://')):
        path = '/' + path

    if not is_thumbor_enabled():
        if path.startswith('http://'):
            return get_camo_url(path)
        return path

    if not user_uploads_or_external(path):
        return path

    source_type = get_source_type(path)
    safe_url = base64.urlsafe_b64encode(path.encode()).decode('utf-8')
    image_url = '%s/source_type/%s' % (safe_url, source_type)
    width, height = map(int, size.split('x'))
    crypto = CryptoURL(key=settings.THUMBOR_KEY)
    encrypted_url = crypto.generate(
        width=width,
        height=height,
        smart=True,
        filters=['no_upscale()', 'sharpen(0.5,0.2,true)'],
        image_url=image_url)

    if settings.THUMBOR_URL == 'http://127.0.0.1:9995':
        # If THUMBOR_URL is the default then thumbor is hosted on same machine
        # as the Zulip server and we should serve a relative URL.
        # We add a /thumbor in front of the relative url because we make
        # use of a proxy pass to redirect request internally in Nginx to 9995
        # port where thumbor is running.
        thumbnail_url = '/thumbor' + encrypted_url
    else:
        thumbnail_url = urllib.parse.urljoin(settings.THUMBOR_URL,
                                             encrypted_url)
    return thumbnail_url
Пример #9
0
def main(arguments=None):
    """Converts a given url with the specified arguments."""

    parsed_options, arguments = get_options(arguments)

    if not arguments:
        sys.stdout.write(
            "Error: The image argument is mandatory. For more information type thumbor-url -h\n"
        )
        sys.exit(1)

    image_url = arguments[0]
    image_url = quote(image_url)

    try:
        config = Config.load(None)
    except Exception:  # pylint: disable=broad-except
        config = None

    if not parsed_options.key and not config:
        sys.stdout.write("Error: The -k or --key argument is mandatory."
                         " For more information type thumbor-url -h\n")
        sys.exit(1)

    security_key, thumbor_params = get_thumbor_params(image_url,
                                                      parsed_options, config)

    crypto = CryptoURL(key=security_key)
    url = crypto.generate(**thumbor_params)
    sys.stdout.write("URL:\n")
    sys.stdout.write(f"{url}\n")
Пример #10
0
def thumb(img, **kwargs):
    '''
        returns a thumbor url for 'img' with **kwargs as thumbor options.

        Positional arguments:
        img -- can be a string representing the image path or any object with a url property.

        Keyword arguments:
        For the complete list of thumbor options
        https://github.com/globocom/thumbor/wiki/Usage
        and the actual implementation for the url generation
        https://github.com/heynemann/libthumbor/blob/master/libthumbor/url.py
    '''
    # url is DNS sharded url
    try:
        url = img.url
    except ValueError:
        # When trying to access the url of an image object when
        # the image does not exist, a ValueError is raised
        logger.exception("No file for object (%s) in thumbor", img.instance)
        return ''
    except AttributeError:
        # If it's an attribute error, assume it's a string already
        url = img

    if settings.THUMBOR_BASE_URL:
        # If THUMBOR_BASE_URL is explicity set, use that
        base = settings.THUMBOR_BASE_URL
    else:
        # otherwise assume that thumbor is setup behind the same
        # CDN behind the `thumbor` namespace.
        scheme, netloc = urlparse.urlsplit(url)[:2]
        base = '{}://{}/thumbor'.format(scheme, netloc)

    url = remove_url_scheme(url)

    # just for code clarity
    thumbor_kwargs = kwargs

    if 'fit_in' not in thumbor_kwargs:
        thumbor_kwargs['fit_in'] = True

    # normalizes url to make it work localy
    if settings.LOCAL:
        thumbor_kwargs['unsafe'] = True

        # strips 'media/' from the start of the url
        if url.startswith('media/'):
            url = url[len('media/'):]

        url = '{}/{}'.format(settings.AWS_S3_CUSTOM_DOMAIN, url)

    thumbor_kwargs['image_url'] = url

    crypto = CryptoURL(key=settings.THUMBOR_KEY)
    path = crypto.generate(**thumbor_kwargs).lstrip('/')

    return '{}/{}'.format(base, path)
Пример #11
0
def own_thumbnail(m, s):
    global thumbor

    proto = 'http%s' % s
    thumbor_base = config.thumbor % {'proto': proto}

    if thumbor is None:
        thumbor = CryptoURL(key=config.thumbor_key)
    return thumbor_base + thumbor.generate(image_url=m(0),
                                           **config.thumbor_pars)
Пример #12
0
 def test_image_with_utf8_url(self):
     with open('./tests/fixtures/images/maracujá.jpg', 'r') as f:
         self.context.modules.storage.put(
             quote(u"http://test.com/maracujá.jpg".encode('utf-8')),
             f.read())
     crypto = CryptoURL('ACME-SEC')
     image_url = self.get_url(
         quote(u"/unsafe/http://test.com/maracujá.jpg".encode('utf-8')))
     url = crypto.generate(image_url=quote(image_url))
     response = self.fetch(url)
     expect(response.code).to_equal(200)
Пример #13
0
 async def test_image_with_utf8_url(self):
     with open("./tests/fixtures/images/maracujá.jpg", "rb") as fixture:
         await self.context.modules.storage.put(
             quote("http://test.com/maracujá.jpg".encode("utf-8")),
             fixture.read(),
         )
     crypto = CryptoURL("ACME-SEC")
     image_url = self.get_url(
         quote("/unsafe/http://test.com/maracujá.jpg".encode("utf-8")))
     url = crypto.generate(image_url=quote(image_url))
     response = await self.async_fetch(url)
     expect(response.code).to_equal(200)
Пример #14
0
 def fit_in_urls(self, original_url, sizes):
     crypto = CryptoURL(key=self._config.THUMBOR_SECURITY_KEY)
     unschemed_original_url = original_url.replace('http://', '')
     urls = {}
     for size in sizes:
         split_size = size.split('x')
         path = crypto.generate(image_url=unschemed_original_url,
                                width=split_size[0],
                                height=split_size[1],
                                fit_in=True)
         urls[size] = self._config.THUMBOR_SERVER_URL.rstrip('/') + path
     return urls
    async def test_shouldnt_auto_convert_png_to_jpg_if_png_has_transparency_with_signed_images(  # NOQA
            self, context_mock):
        context_mock.return_value = self.context
        crypto = CryptoURL("ACME-SEC")
        url = crypto.generate(image_url="watermark.png")
        self.context.request = self.get_request(url=url)

        # save on result storage
        response = await self.async_fetch(url)
        expect(response.code).to_equal(200)
        expect(response.headers).not_to_include("Vary")
        expect(response.body).to_be_png()
    def _fetch_images(self):
        crypto = CryptoURL(key=self.context.server.security_key)

        image_ops = []
        if not hasattr(self.context.config,
                       'DISTRIBUTED_COLLAGE_FILTER_HTTP_LOADER'):
            self.context.config.DISTRIBUTED_COLLAGE_FILTER_HTTP_LOADER = 'thumbor.loaders.http_loader'
        self.context.modules.importer.import_item(
            'DISTRIBUTED_COLLAGE_FILTER_HTTP_LOADER')
        loader = self.context.modules.importer.distributed_collage_filter_http_loader

        for i, url in enumerate(self.urls):
            width = self.image_width if i < len(
                self.urls) - 1 else self.last_image_width

            params = {
                'width': int(width),
                'height': int(self.context.request.height),
                'image_url': url,
                'smart': True,
                'halign': 'center',
                'valign': 'middle',
                'filters': ['quality(100)'],
            }
            thumbor_host = getattr(
                self.context.config,
                'DISTRIBUTED_COLLAGE_FILTER_THUMBOR_SERVER_URL',
                '%s://%s' % (
                    self.context.request_handler.request.protocol,
                    self.context.request_handler.request.host,
                ),
            )
            encrypted_url = '%s%s' % (thumbor_host, crypto.generate(**params))
            image_ops.append(loader.load(self.context, encrypted_url))

        images = yield image_ops

        successful = all([image.successful for image in images])
        if not successful:
            logger.error(
                'Retrieving at least one of the collaged images failed: %s' %
                (', '.join(
                    [image.error
                     for image in images if not image.successful]), ))
            self.callback()
            return

        max_age = min([
            self.get_max_age(image.metadata.get('Cache-Control'), self.max_age)
            for image in images
        ])
        self.assembly_images(images)
        self.callback()
Пример #17
0
    async def test_image_already_generated_by_thumbor(self):
        with open("./tests/fixtures/images/image.jpg", "rb") as fixture:
            await self.context.modules.storage.put(
                quote("http://test.com/smart/image.jpg"), fixture.read())
        crypto = CryptoURL("ACME-SEC")
        image_url = self.get_url(
            crypto.generate(
                image_url=quote("http://test.com/smart/image.jpg")))
        url = crypto.generate(image_url=quote(image_url))

        response = await self.async_fetch(url)
        expect(response.code).to_equal(200)
Пример #18
0
    def test_image_already_generated_by_thumbor(self):
        with open('./tests/fixtures/images/image.jpg', 'r') as f:
            self.context.modules.storage.put(
                quote("http://test.com/smart/image.jpg"), f.read())
        crypto = CryptoURL('ACME-SEC')
        image_url = self.get_url(
            crypto.generate(
                image_url=quote("http://test.com/smart/image.jpg")))
        url = crypto.generate(image_url=quote(image_url))

        response = self.fetch(url)
        expect(response.code).to_equal(200)
Пример #19
0
def test_thumbor_can_decrypt_lib_thumbor_generated_url_new_format():
    key = "my-security-key"
    image = "s.glbimg.com/et/bb/f/original/2011/03/24/VN0JiwzmOw0b0lg.jpg"
    thumbor_signer = Signer(key)

    crypto = CryptoURL(key=key)

    url = crypto.generate(width=300, height=200, smart=True, image_url=image)

    reg = "/([^/]+)/(.+)"
    (signature, url) = re.match(reg, url).groups()

    assert thumbor_signer.validate(signature, url)
Пример #20
0
    def test_can_auto_convert_jpeg_from_result_storage(self, context_mock):
        context_mock.return_value = self.context
        crypto = CryptoURL('ACME-SEC')
        url = crypto.generate(image_url=quote("http://test.com/smart/image.jpg"))
        self.context.request = self.get_request(url=url, accepts_webp=True)
        with open('./tests/fixtures/images/image.webp', 'r') as f:
            self.context.modules.result_storage.put(f.read())

        response = self.get_as_webp(url)
        expect(response.code).to_equal(200)
        expect(response.headers).to_include('Vary')
        expect(response.headers['Vary']).to_include('Accept')
        expect(response.body).to_be_webp()
    async def test_should_auto_convert_png_to_webp_if_auto_webp_is_true_and_png_has_transparency_with_signed_images(  # NOQA
            self, context_mock):
        self.config.AUTO_WEBP = True
        context_mock.return_value = self.context
        crypto = CryptoURL("ACME-SEC")
        url = crypto.generate(image_url="watermark.png")
        self.context.request = self.get_request(url=url)

        # save on result storage
        response = await self.get_as_webp(url)
        expect(response.code).to_equal(200)
        expect(response.headers).to_include("Vary")
        expect(response.body).to_be_webp()
Пример #22
0
 def test_thumbor_filter(self):
     testing.setUp(settings={
         'thumbor.security_key': 'foo',
     })
     crypto = CryptoURL(key='foo')
     self.assertEqual(
         thumbor_filter({}, 'image', 25, 25),
         crypto.generate(width=25, height=25, image_url='image'))
     self.assertEqual(thumbor_filter({}, 'image', 25),
                      crypto.generate(width=25, image_url='image'))
     self.assertEqual(
         thumbor_filter({}, 'image', 25, None),
         crypto.generate(width=25, height=0, image_url='image'))
    async def test_should_auto_convert_png_to_jpg_with_signed_images(
            self, context_mock):
        context_mock.return_value = self.context
        crypto = CryptoURL("ACME-SEC")
        url = crypto.generate(
            image_url="Giunchedi%2C_Filippo_January_2015_01.png")
        self.context.request = self.get_request(url=url)

        context_mock.return_value = self.context
        response = await self.async_fetch(url)
        expect(response.code).to_equal(200)
        expect(response.headers).not_to_include("Vary")
        expect(response.body).to_be_jpeg()
Пример #24
0
def thumbor_filter(ctx, image, width, height=0):
    registry = get_current_registry(context=ctx)
    security_key = registry.settings.get('thumbor.security_key')
    if not all([security_key, image]):
        return ''

    # libthumbor generates an invalid url when height is None:
    # https://github.com/thumbor/libthumbor/blob/master/libthumbor/url.py#L19
    # Coerce it to 0. This scales the height proportionally.
    if height is None:
        height = 0

    crypto = CryptoURL(key=security_key)
    return crypto.generate(width=width, height=height, image_url=image)
Пример #25
0
 def thumborurl(image, size):
     '''
     Método que cria, através da libthumbor
     a url codificada para exibição de imagens na galeria
     '''
     #print "CODIFICANDO:", size, image
     crypto = CryptoURL(key=app.config['THUMBOR_KEY'])
     codigo = crypto.generate(
         width=size[0] if isinstance(size[0], int) else None,
         height=size[1] if isinstance(size[1], int) else None,
         smart=True,
         image_url=image.replace('http://', ''))
     #print "CODIGO:", codigo
     return app.config['THUMBOR_URL'] + codigo
    async def test_should_auto_convert_png_to_webp_if_auto_webp_is_true_with_signed_images(  # NOQA
            self, context_mock):
        self.config.AUTO_WEBP = True
        context_mock.return_value = self.context
        crypto = CryptoURL("ACME-SEC")
        url = crypto.generate(
            image_url="Giunchedi%2C_Filippo_January_2015_01.png")
        self.context.request = self.get_request(url=url, accepts_webp=True)

        # save on result storage
        response = await self.get_as_webp(url)
        expect(response.code).to_equal(200)
        expect(response.headers).to_include("Vary")
        expect(response.body).to_be_webp()
    async def test_can_auto_convert_jpeg_from_result_storage(
            self, context_mock):  # NOQA
        context_mock.return_value = self.context
        crypto = CryptoURL("ACME-SEC")
        url = crypto.generate(
            image_url=quote("http://test.com/smart/image.jpg"))
        self.context.request = self.get_request(url=url, accepts_webp=True)
        with open("./tests/fixtures/images/image.webp", "rb") as fixture:
            await self.context.modules.result_storage.put(fixture.read())

        response = await self.get_as_webp(url)
        expect(response.code).to_equal(200)
        expect(response.headers).to_include("Vary")
        expect(response.headers["Vary"]).to_include("Accept")
        expect(response.body).to_be_webp()
Пример #28
0
def generate_thumbnail_url(path: str,
                           size: str = '0x0',
                           is_camo_url: bool = False) -> str:
    path = urljoin("/", path)

    if not is_thumbor_enabled():
        if is_safe_url(path, allowed_hosts=None):
            return path
        return get_camo_url(path)

    if is_safe_url(
            path,
            allowed_hosts=None) and not path.startswith("/user_uploads/"):
        return path

    source_type = get_source_type(path)
    safe_url = base64.urlsafe_b64encode(path.encode()).decode('utf-8')
    image_url = f'{safe_url}/source_type/{source_type}'
    width, height = map(int, size.split('x'))
    crypto = CryptoURL(key=settings.THUMBOR_KEY)

    smart_crop_enabled = True
    apply_filters = ['no_upscale()']
    if is_camo_url:
        smart_crop_enabled = False
        apply_filters.append('quality(100)')
    if size != '0x0':
        apply_filters.append('sharpen(0.5,0.2,true)')

    encrypted_url = crypto.generate(
        width=width,
        height=height,
        smart=smart_crop_enabled,
        filters=apply_filters,
        image_url=image_url,
    )

    if settings.THUMBOR_URL == 'http://127.0.0.1:9995':
        # If THUMBOR_URL is the default then thumbor is hosted on same machine
        # as the Zulip server and we should serve a relative URL.
        # We add a /thumbor in front of the relative url because we make
        # use of a proxy pass to redirect request internally in Nginx to 9995
        # port where thumbor is running.
        thumbnail_url = '/thumbor' + encrypted_url
    else:
        thumbnail_url = urllib.parse.urljoin(settings.THUMBOR_URL,
                                             encrypted_url)
    return thumbnail_url
Пример #29
0
    def get(self, **kwargs):
        # check if request is valid
        yield gen.maybe_future(self.check_pdf(kwargs.copy()))

        pdf = PDF(self.context)
        pdf_path = kwargs.pop('pdf')
        url_parts, pdf_url = pdf.url_parts(pdf_path)
        preview_path = pdf_path.replace('/pdf/', '').replace('.pdf', '.png')

        # Check if preview image already exists
        path = quote(preview_path.encode('utf-8'))
        exists = yield gen.maybe_future(pdf.get(path))
        if not exists:
            # create a new preview
            data = yield self.create_preview(pdf_url)
            if not data:
                raise tornado.web.HTTPError(400)
            # store it in storage
            yield gen.maybe_future(pdf.put(path, data))
        else:
            logger.debug('PDF preview already exists..')

        crypto = CryptoURL(key=self.context.server.security_key)
        options = {k: v for k, v in kwargs.items() if v and k != 'hash'}
        preview_url = crypto.generate(image_url=preview_path, **options)
        kwargs['hash'] = RequestParser.path_to_parameters(preview_url)['hash']

        # Patch the request uri to allow normal thumbor operations
        self.request.uri = preview_url
        self.request.path = preview_url

        kwargs['request'] = self.request
        kwargs['image'] = preview_path
        self.context.request = RequestParameters(**kwargs)

        # set valid file name in headers
        name = os.path.basename(kwargs.get('image', None))
        if name:
            self.set_header('Content-Disposition',
                            'inline; filename="{name}"'.format(name=name))

        # Call the original ImageHandler.get method to serve the image.
        super(PDFHandler, self).get(**kwargs)
Пример #30
0
    def get_image_url(self, image_host, image_uuid, width=None, height=None):
        security_key = self.settings.get('thumbor.security_key')
        if not (security_key and image_host and image_uuid):
            return ''

        crypto = CryptoURL(key=security_key)

        if not (width or height):
            image_url = crypto.generate(image_url=image_uuid)
        elif width and height:
            image_url = crypto.generate(
                width=width, height=height, image_url=image_uuid)
        elif width:
            image_url = crypto.generate(
                width=width, height=0, image_url=image_uuid)
        else:
            image_url = crypto.generate(
                width=0, height=height, image_url=image_uuid)

        return urljoin(image_host, image_url)