123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- import os
- import re
- import time
- from datetime import timedelta
- import datetime
- from io import BytesIO
- from fastapi import Depends, FastAPI, HTTPException, status, UploadFile, APIRouter, File
- from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
- from starlette.responses import StreamingResponse, FileResponse
- from config.config import MinioOperate, SetCache
- from models.model import *
- from utils.jwt import authenticate_user, ACCESS_TOKEN_EXPIRE_MINUTES, create_access_token, get_current_active_user, \
- fake_users_db
- # 创建minio对象
- minio_class = MinioOperate()
- # 连接minio
- minio_client = minio_class.link_minio()
- # 创建bucket
- minio_class.create_bucket(["file", "image"])
- # 初始化缓存
- cache = SetCache(maxsize=128, ttl=100)
- router = APIRouter()
- @router.post("/token", response_model=Token)
- async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
- user = authenticate_user(fake_users_db, form_data.username, form_data.password)
- if not user:
- raise HTTPException(
- status_code=status.HTTP_401_UNAUTHORIZED,
- detail="Incorrect username or password",
- headers={"WWW-Authenticate": "Bearer"},
- )
- # 设置令牌过期时间
- access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
- # 创建访问令牌
- access_token = create_access_token(
- data={"sub": user.username}, expires_delta=access_token_expires
- )
- return {"access_token": access_token, "token_type": "bearer"}
- # minio ?上传文件时在重复时,需要修改文件名
- @router.post("/file")
- async def create_file(file: UploadFile = File(...)):
- timestamp = str(time.time()).ljust(18, "0")
- uid = re.sub(r"\.", "", timestamp)
- front, ext = os.path.splitext(file.filename)
- file_name = uid + ext # 168549427474778.png
- data = await file.read()
- file_stream = BytesIO(initial_bytes=data)
- size = len(data)
- date = str(datetime.date.today())
- object_path = date + "/{}".format(file_name)
- if (minio_client.put_object(
- "image",
- object_path,
- file_stream,
- size
- )):
- return {"status": 200, "data": [file_name], "msg": ""}
- else:
- return {"status": 400, "data": [], "msg": "Post Failed!"}
- # 图片预览【把后缀jpg去掉也可以变成下载】
- # response = StreamingResponse(file_content,media_type='image/jpg)
- # 图片下载功能
- # response = StreamingResponse(file_content,
- # media_type='application/octet-stream',
- # headers={"Content-Disposition": f"attachment; filename={uid}"})
- @router.get("/file/{uid}")
- async def download_file(uid: str):
- try:
- timestamp, ext = os.path.splitext(uid)
- timestamp = float(str(float(timestamp) / 10000000).ljust(18, "0"))
- object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
- "0") + "-" \
- + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
- file_obj = minio_client.get_object("image", object_path)
- if not cache.get(uid):
- # 添加缓存
- # print("第一次获取,添加到缓存")
- cache.add(uid, file_obj.read())
- else:
- # print("从缓存中找到uid,获取缓存")
- file_bytes = cache.get(uid)
- return StreamingResponse(BytesIO(file_bytes), media_type="image/{}".format(ext[1:]))
- file_content = BytesIO(file_obj.read())
- response = StreamingResponse(file_content, media_type='image/{}'.format(ext[1:]))
- except Exception as e:
- return {"status": 400, "data": [], "msg": "Get Failed!"}
- # return response
- return {"status": 200, "data": [uid], "msg": ""}
- # 删除 鉴权 current_user: User = Depends(get_current_active_user)
- @router.delete("/file/{uid}")
- async def delete_file(uid: str):
- try:
- timestamp, ext = os.path.splitext(uid)
- timestamp = float(str(float(timestamp) / 10000000).ljust(18, "0"))
- object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
- "0") + "-" \
- + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
- minio_client.get_object("image", object_path)
- minio_client.remove_object("image", object_path)
- return {"status": 200, "data": [], "msg": "Delete Success!"}
- except:
- return {"status": 404, "data": [], "msg": "Not Found"}
|