files.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import os
  2. import re
  3. import time
  4. from datetime import timedelta
  5. import datetime
  6. from io import BytesIO
  7. from fastapi import Depends, FastAPI, HTTPException, status, UploadFile, APIRouter, File
  8. from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
  9. from starlette.responses import StreamingResponse, FileResponse
  10. from config.config import MinioOperate, SetCache
  11. from models.model import *
  12. from utils.jwt import authenticate_user, ACCESS_TOKEN_EXPIRE_MINUTES, create_access_token, get_current_active_user, \
  13. fake_users_db
  14. # 创建minio对象
  15. minio_class = MinioOperate()
  16. # 连接minio
  17. minio_client = minio_class.link_minio()
  18. # 创建bucket
  19. minio_class.create_bucket(["file", "image"])
  20. # 初始化缓存
  21. cache = SetCache(maxsize=128, ttl=100)
  22. router = APIRouter()
  23. @router.post("/token", response_model=Token)
  24. async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
  25. user = authenticate_user(fake_users_db, form_data.username, form_data.password)
  26. if not user:
  27. raise HTTPException(
  28. status_code=status.HTTP_401_UNAUTHORIZED,
  29. detail="Incorrect username or password",
  30. headers={"WWW-Authenticate": "Bearer"},
  31. )
  32. # 设置令牌过期时间
  33. access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
  34. # 创建访问令牌
  35. access_token = create_access_token(
  36. data={"sub": user.username}, expires_delta=access_token_expires
  37. )
  38. return {"access_token": access_token, "token_type": "bearer"}
  39. # minio ?上传文件时在重复时,需要修改文件名
  40. @router.post("/file")
  41. async def create_file(file: UploadFile = File(...)):
  42. timestamp = str(time.time()).ljust(18, "0")
  43. uid = re.sub(r"\.", "", timestamp)
  44. front, ext = os.path.splitext(file.filename)
  45. file_name = uid + ext # 168549427474778.png
  46. data = await file.read()
  47. file_stream = BytesIO(initial_bytes=data)
  48. size = len(data)
  49. date = str(datetime.date.today())
  50. object_path = date + "/{}".format(file_name)
  51. if (minio_client.put_object(
  52. "image",
  53. object_path,
  54. file_stream,
  55. size
  56. )):
  57. return {"status": 200, "data": [file_name], "msg": ""}
  58. else:
  59. return {"status": 400, "data": [], "msg": "Post Failed!"}
  60. # 图片预览【把后缀jpg去掉也可以变成下载】
  61. # response = StreamingResponse(file_content,media_type='image/jpg)
  62. # 图片下载功能
  63. # response = StreamingResponse(file_content,
  64. # media_type='application/octet-stream',
  65. # headers={"Content-Disposition": f"attachment; filename={uid}"})
  66. @router.get("/file/{uid}")
  67. async def download_file(uid: str):
  68. try:
  69. timestamp, ext = os.path.splitext(uid)
  70. timestamp = float(str(float(timestamp) / 10000000).ljust(18, "0"))
  71. object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
  72. "0") + "-" \
  73. + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
  74. file_obj = minio_client.get_object("image", object_path)
  75. if not cache.get(uid):
  76. # 添加缓存
  77. # print("第一次获取,添加到缓存")
  78. cache.add(uid, file_obj.read())
  79. else:
  80. # print("从缓存中找到uid,获取缓存")
  81. file_bytes = cache.get(uid)
  82. return StreamingResponse(BytesIO(file_bytes), media_type="image/{}".format(ext[1:]))
  83. file_content = BytesIO(file_obj.read())
  84. response = StreamingResponse(file_content, media_type='image/{}'.format(ext[1:]))
  85. except Exception as e:
  86. return {"status": 400, "data": [], "msg": "Get Failed!"}
  87. # return response
  88. return {"status": 200, "data": [uid], "msg": ""}
  89. # 删除 鉴权 current_user: User = Depends(get_current_active_user)
  90. @router.delete("/file/{uid}")
  91. async def delete_file(uid: str):
  92. try:
  93. timestamp, ext = os.path.splitext(uid)
  94. timestamp = float(str(float(timestamp) / 10000000).ljust(18, "0"))
  95. object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
  96. "0") + "-" \
  97. + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
  98. minio_client.get_object("image", object_path)
  99. minio_client.remove_object("image", object_path)
  100. return {"status": 200, "data": [], "msg": "Delete Success!"}
  101. except:
  102. return {"status": 404, "data": [], "msg": "Not Found"}