import oss2 import uuid import datetime from django.conf import settings from urllib.parse import urljoin import os import logging logger = logging.getLogger(__name__) class OSSUploader: """ 通用OSS文件上传工具类 """ def __init__(self, base_dir='upload'): """ 初始化OSS上传器 Args: base_dir: 文件存储的基础目录 """ self.base_dir = base_dir self.access_key_id = settings.AUDIO_SERVICE_CONFIG['aliyun']['oss_key_id'] self.access_key_secret = settings.AUDIO_SERVICE_CONFIG['aliyun']['oss_key_secret'] self.bucket_name = settings.AUDIO_SERVICE_CONFIG['aliyun']['oss_bucket'] self.endpoint = settings.AUDIO_SERVICE_CONFIG['aliyun']['oss_endpoint'] self.host = settings.AUDIO_SERVICE_CONFIG['aliyun']['oss_host'] # 初始化OSS客户端 self.auth = oss2.Auth(self.access_key_id, self.access_key_secret) self.bucket = oss2.Bucket(self.auth, self.endpoint, self.bucket_name) def upload_file(self, file_obj, is_permanent=False, filename=None): """ 上传文件到OSS Args: file_obj: 文件对象/二进制数据 is_permanent: 是否永久保存,False表示临时文件 filename: 自定义文件名,如果为None则生成随机名称 Returns: dict: 包含文件URL和OSS Key """ try: # 生成今天的日期作为子目录 today = datetime.datetime.now().strftime('%Y%m%d') # 确定存储类型目录 storage_type = 'permanent' if is_permanent else 'temporary' # 生成文件名 if not filename: # 生成随机文件名 random_uuid = uuid.uuid4() if hasattr(file_obj, 'name'): # 获取原始文件扩展名 _, ext = os.path.splitext(file_obj.name) file_name = f"{random_uuid}{ext}" else: file_name = f"{random_uuid}" else: file_name = filename # 构建OSS路径 oss_key = f"{self.base_dir}/{storage_type}/{today}/{file_name}" # 上传文件 if hasattr(file_obj, 'read'): content = file_obj.read() self.bucket.put_object(oss_key, content) else: # 假设file_obj是二进制数据 self.bucket.put_object(oss_key, file_obj) # 生成URL file_url = urljoin(self.host, oss_key) logger.info(f"File uploaded to OSS: {oss_key}") return { 'url': file_url, 'key': oss_key, 'is_permanent': is_permanent } except Exception as e: logger.error(f"Error uploading file to OSS: {str(e)}") raise