import requests from fastapi import UploadFile from app.core.biz_exception import NotFoundError, PermissionDeniedError, BizLogicError from app.core.logger import logger class SeaweedFSService: MASTER_URL = "http://127.0.0.1:9333" # 你的 SeaweedFS master 地址 @classmethod def upload(cls, file: UploadFile): """上传文件到 SeaweedFS""" try: # 1️⃣ 获取可上传的 volume 地址 assign_resp = requests.get(f"{cls.MASTER_URL}/dir/assign", timeout=5) assign_data = assign_resp.json() fid = assign_data["fid"] public_url = assign_data["publicUrl"] # 2️⃣ 上传文件数据 upload_url = f"http://{public_url}/{fid}" download_url = f"http://45.137.220.138:8888/api/resource/download_file?fid={fid}" files = {"file": (file.filename, file.file, file.content_type)} upload_resp = requests.post(upload_url, files=files, timeout=10) if upload_resp.status_code == 201: return {"fid": fid, "url": download_url} else: raise BizLogicError(f"file upload error: {upload_resp.text}") except Exception as e: raise BizLogicError(f"file upload exception: {e}") @classmethod def get(cls, fid: str): """根据 fid 读取文件""" try: resp = requests.get(f"{cls.MASTER_URL}/dir/lookup?volumeId={fid.split(',')[0]}", timeout=5) data = resp.json() if not data.get("locations"): return None public_url = data["locations"][0]["publicUrl"] file_url = f"http://{public_url}/{fid}" file_resp = requests.get(file_url, timeout=10) if file_resp.status_code == 200: return file_resp.content, file_resp.headers.get("Content-Type", "application/octet-stream") else: return None except Exception as e: logger.exception(f"SeaweedFS 读取异常, 原因={e}") return None @classmethod def delete(cls, fid: str): """删除文件""" try: resp = requests.get(f"{cls.MASTER_URL}/dir/lookup?volumeId={fid.split(',')[0]}", timeout=5) data = resp.json() if not data.get("locations"): return False public_url = data["locations"][0]["publicUrl"] delete_url = f"http://{public_url}/{fid}" del_resp = requests.delete(delete_url, timeout=10) return del_resp.status_code == 202 except Exception as e: logger.exception(f"SeaweedFS 删除异常, 原因={e}") return False