dvlyadmin_pro/backend/utils/qiniu_storage.py

66 lines
2.4 KiB
Python

from qiniu import Auth, put_file, put_data
from django.conf import settings
import time
import os
from PIL import Image
from io import BytesIO
import logging
logger = logging.getLogger(__name__)
class QiniuStorage:
def __init__(self):
self.q = Auth(settings.QINIU_ACCESS_KEY, settings.QINIU_SECRET_KEY)
self.bucket_name = settings.QINIU_BUCKET_NAME
self.domain = settings.QINIU_BUCKET_DOMAIN
self.max_size = 5 * 1024 * 1024 # 5MB
self.allowed_types = ['.jpg', '.jpeg', '.png', '.gif']
def compress_image(self, image_data):
"""无损压缩图片"""
img = Image.open(BytesIO(image_data))
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
output = BytesIO()
# 保持原始尺寸,仅优化质量
img.save(output, format='JPEG', quality=85, optimize=True)
return output.getvalue()
def upload_data(self, file_data, file_path):
"""上传文件数据"""
# 检查文件大小
if file_data.size > self.max_size:
return {'code': 400, 'msg': f'文件大小不能超过{self.max_size/1024/1024}MB'}
# 检查文件类型
ext = os.path.splitext(file_data.name)[1].lower()
if ext not in self.allowed_types:
return {'code': 400, 'msg': f'只支持{",".join(self.allowed_types)}格式的图片'}
# 压缩图片
try:
compressed_data = self.compress_image(file_data.read())
except Exception as e:
return {'code': 400, 'msg': f'图片压缩失败:{str(e)}'}
token = self.q.upload_token(self.bucket_name)
timestamp = time.strftime('%Y-%m-%d/%Y%m%d%H%M%S', time.localtime())
key = f"{file_path}/{timestamp}_{str(int(time.time()*1000))[-3:]}{ext}"
try:
ret, info = put_data(token, key, compressed_data)
if info.status_code == 200:
base_url = f'http://{self.domain}/{key}'
private_url = self.q.private_download_url(base_url, expires=3600*24*365)
return {
'code': 200,
'url': private_url,
'msg': '上传成功'
}
# 在 except 中添加日志
except Exception as e:
logger.error(f"七牛云上传失败: {str(e)}")
return {
'code': 400,
'msg': f'上传失败:{str(e)}'
}