files.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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
  10. from config import config
  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 = config.MinioOperate()
  16. # 连接minio
  17. minio_client = minio_class.link_minio()
  18. # 创建bucket
  19. minio_class.create_bucket(["file", "image"])
  20. router = APIRouter()
  21. @router.post("/token", response_model=Token)
  22. async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
  23. user = authenticate_user(fake_users_db, form_data.username, form_data.password)
  24. if not user:
  25. raise HTTPException(
  26. status_code=status.HTTP_401_UNAUTHORIZED,
  27. detail="Incorrect username or password",
  28. headers={"WWW-Authenticate": "Bearer"},
  29. )
  30. # 设置令牌过期时间
  31. access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
  32. # 创建访问令牌
  33. access_token = create_access_token(
  34. data={"sub": user.username}, expires_delta=access_token_expires
  35. )
  36. return {"access_token": access_token, "token_type": "bearer"}
  37. # minio ?上传文件时在重复时,需要修改文件名
  38. @router.post("/file")
  39. async def create_file(file: UploadFile = File(...)):
  40. timestamp = str(time.time()).ljust(18,"0")
  41. uid = re.sub(r"\.", "", timestamp)
  42. front, ext = os.path.splitext(file.filename)
  43. file_name = uid + ext # 168549427474778.png
  44. data = await file.read()
  45. file_stream = BytesIO(initial_bytes=data)
  46. size = len(data)
  47. date = str(datetime.date.today())
  48. object_path = date + "/{}".format(file_name)
  49. if (minio_client.put_object(
  50. "image",
  51. object_path,
  52. file_stream,
  53. size
  54. )):
  55. return {"status": 200, "data": [file_name], "msg": ""}
  56. else:
  57. return {"status": 400, "data": [], "msg": "Post Failed!"}
  58. # 图片预览
  59. # response = StreamingResponse(file_content,media_type='image/jpg)
  60. # 图片下载功能
  61. @router.get("/file/{uid}")
  62. async def download_file(uid: str):
  63. try:
  64. timestamp, ext = os.path.splitext(uid)
  65. timestamp = float(str(float(timestamp) / 10000000).ljust(18,"0"))
  66. object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
  67. "0") + "-" \
  68. + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
  69. file_obj = minio_client.get_object("image", object_path)
  70. file_content = BytesIO(file_obj.read())
  71. # response = StreamingResponse(file_content,
  72. # media_type='application/octet-stream',
  73. # headers={"Content-Disposition": f"attachment; filename={uid}"})
  74. response = StreamingResponse(file_content, media_type='image/png')
  75. except Exception as e:
  76. return {"status": 400, "data": [], "msg": "Get Failed!"}
  77. return response
  78. # 删除 鉴权 current_user: User = Depends(get_current_active_user)
  79. @router.delete("/file/{uid}")
  80. async def delete_file(uid: str):
  81. try:
  82. timestamp, ext = os.path.splitext(uid)
  83. timestamp = float(str(float(timestamp) / 10000000).ljust(18,"0"))
  84. object_path = str(time.localtime(timestamp).tm_year) + "-" + str(time.localtime(timestamp).tm_mon).rjust(2,
  85. "0") + "-" \
  86. + str(time.localtime(timestamp).tm_mday).rjust(2, "0") + "/{}".format(uid)
  87. minio_client.get_object("image", object_path)
  88. minio_client.remove_object("image", object_path)
  89. return {"status": 200, "data": [], "msg": "Delete Success!"}
  90. except:
  91. return {"status": 404, "data": [], "msg": "Not Found"}