Example #1
0
def crop_image(image: Image.Image, x: int, y: int, w: int, h: int) -> Image.Image:
    logger.debug(
        '图片裁剪:裁剪图片 {image},'
        '裁剪区域 x:{x}+{w} y:{y}+{h}'.format(image=image, x=x, y=y, w=w, h=h))
    image = image.crop((x, y, x + w, y + h))
    logger.debug('图片裁剪:完成√')
    return image
Example #2
0
def resize_image(image: Image.Image, max_width: int, max_height: int) -> Image.Image:
    logger.debug('图片缩放:缩放图片 {image},'
                 '目标尺寸 {width} * {height}'.format(image=image, width=max_width,
                                                  height=max_height))
    w, h = image.size
    if w > max_width or h > max_height:
        ratio = min(max_width / w, max_height / h)
        image = image.resize((int(w * ratio), int(h * ratio)), Image.ANTIALIAS)
    logger.debug('图片缩放:完成√')
    return image
Example #3
0
def generate_thumbnails(image: Image, sizes: dict, target_format: str = 'PNG',
                        target_mode: str = 'RGBA', optimize: bool = False) -> dict:
    thumbs = {}
    for size, limits in sizes.items():
        logger.debug('缩略图生成:生成缩略图 {size} {limits}'.format(size=size, limits=limits))
        resized_image = resize_image(image, limits['WIDTH'], limits['HEIGHT'])
        compressed_io = compress_image(resized_image, limits['SIZE'], target_format, target_mode,
                                       optimize)
        thumbs[size] = compressed_io
    logger.debug('缩略图生成:完成√')
    return thumbs
Example #4
0
 def url(self, name, virtual_name: str = None, sign: bool = True):
     name = self._get_target_name(name)
     logger.debug('OSS存储后端:生成url {path},签名:{sign}'.format(path=name,
                                                          sign=sign))
     params = dict()
     if not virtual_name:
         virtual_name = name
     params.update(_make_content_headers(virtual_name))
     if sign:
         return self.bucket.sign_url(
             'GET', name, OSS_SIGNED_URL_EXPIRE,
             params=params)  # default access link expire time: 5min
     else:
         return self.bucket._make_url(self.bucket_name, name)
Example #5
0
    def listdir(self, name):
        name = self._get_target_name(name)
        logger.debug('OSS存储后端:列目录 {path}'.format(path=name))
        if name and name.endswith('/'):
            name = name[:-1]

        files = []
        dirs = set()

        for obj in ObjectIterator(self.bucket, prefix=name, delimiter='/'):
            if obj.is_prefix():
                dirs.add(obj.key)
            else:
                files.append(obj.key)

        return list(dirs), files
    def get_preferred_language(cls, request):
        try:
            lang_codes = request.headers['Accept-Language'].split(';')
            lang_codes = [x.split(',') for x in lang_codes]

            accept_langs = set()
            accept_langs.add(cls.LANGUAGE_CODE_MAPPING[lang_codes[0][0]])
            for lang in lang_codes[1:]:
                try:
                    accept_langs.add(cls.LANGUAGE_CODE_MAPPING[lang[1]])
                except KeyError:
                    pass
            for lang in accept_langs:
                if lang in settings.LANGUAGES:
                    return lang
        except Exception:
            pass  # 忽略处理过程中的所有错误,并返回网站默认语言
            logger.debug('语言中间件:读取Accept-Language发生错误,返回系统默认语言')
        return settings.LANGUAGE_CODE
Example #7
0
def compress_image(image: Image.Image, target_size: int, target_format: str = 'PNG',
                   target_mode: str = 'RGBA', optimize: bool = False) -> BytesIO:
    image = image.convert(mode=target_mode)
    temp_io = BytesIO()
    image.save(temp_io, target_format, optimize=optimize)
    w, h = image.size
    ratio = 1
    logger.debug(
        '图片压缩:压缩图片 {image}({size}),目标大小 {target_size},'
        '目标格式 {target_format}'.format(image=image,
                                      size=temp_io.tell(),
                                      target_size=target_size,
                                      target_format=target_format))
    while temp_io.tell() > target_size:
        ratio -= 0.1
        if ratio <= 0:
            raise Exception(_('图片压缩失败!'))
        resized_image = image.resize(w * ratio, h * ratio)
        temp_io = BytesIO()
        resized_image.save(temp_io, target_format, optimize=optimize)
    logger.debug('图片压缩:完成√')
    return temp_io
 def __call__(self, request):
     logger.debug('语言中间件:收到请求,开始处理。')
     user = request.user
     if user.is_authenticated:
         profile = user.profile
         lang = profile.language
         logger.debug('语言中间件:成功获取到UserProfile')
         translation.activate(lang)
         response = self.get_response(request)
         response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
     elif settings.LANGUAGE_COOKIE_NAME in request.COOKIES:
         logger.debug('语言中间件:用户未登录,读取COOKIE')
         lang = request.COOKIES[settings.LANGUAGE_COOKIE_NAME]
         if lang in settings.LANGUAGES:
             translation.activate(lang)
         response = self.get_response(request)
     else:
         logger.debug('语言中间件:用户未登录,读取Accept-Language请求头')
         lang = self.get_preferred_language(request)
         translation.activate(lang)
         response = self.get_response(request)
         response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
     logger.debug('语言中间件:语言已设定为 %s' % lang)
     return response
Example #9
0
    def _save(self, name, content: File):
        # 为保证django行为的一致性,保存文件时,应该返回相对于`media path`的相对路径。

        target_name = self._get_target_name(name)

        logger.debug('OSS存储后端:保存文件 %s' % target_name)

        content.open()

        # 默认分片大小 1MB
        DEFAULT_CHUNK_SIZE = 1 * 1024 * 1024

        logger.debug('OSS存储后端:读取完成,文件大小 %d' % content.size)
        if not content.multiple_chunks(chunk_size=DEFAULT_CHUNK_SIZE):
            logger.debug('OSS存储后端:不分片,开始上传')
            # 不分片
            content_str = content.file.read()
            self.bucket.put_object(target_name, content_str)
        else:
            logger.debug('OSS存储后端:分片,开始上传')
            # 改用分片上传方式
            upload_id = self.bucket.init_multipart_upload(
                target_name).upload_id
            parts = []
            part_id = 1

            for chunk in content.chunks(chunk_size=DEFAULT_CHUNK_SIZE):
                # TODO Create an API endpoint for getting uploading process
                result = self.bucket.upload_part(target_name, upload_id,
                                                 part_id, chunk)
                parts.append(PartInfo(part_id, result.etag))
                part_id += 1
                logger.debug('OSS存储后端:上传分片 #%d' % part_id)
            result = self.bucket.complete_multipart_upload(
                target_name, upload_id, parts)

        logger.debug('OSS存储后端:上传完毕,关闭文件')
        content.close()
        return self._clean_name(name)
Example #10
0
 def _open(self, name, mode='rb'):
     name = self._get_target_name(name)
     logger.debug('OSS存储后端:打开文件 {name},模式 {mode}'.format(name=name,
                                                         mode=mode))
     file = AliyunFile(name, self, mode)
     return file