files.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. import logging
  2. import os
  3. import shutil
  4. import uuid
  5. from pathlib import Path
  6. from typing import Optional
  7. from apps.webui.models.files import FileForm, FileModel, Files
  8. from config import UPLOAD_DIR
  9. from constants import ERROR_MESSAGES
  10. from env import SRC_LOG_LEVELS
  11. from fastapi import APIRouter, Depends, File, HTTPException, UploadFile, status
  12. from fastapi.responses import FileResponse
  13. from utils.utils import get_admin_user, get_verified_user
  14. log = logging.getLogger(__name__)
  15. log.setLevel(SRC_LOG_LEVELS["MODELS"])
  16. router = APIRouter()
  17. ############################
  18. # Upload File
  19. ############################
  20. @router.post("/")
  21. def upload_file(file: UploadFile = File(...), user=Depends(get_verified_user)):
  22. log.info(f"file.content_type: {file.content_type}")
  23. try:
  24. unsanitized_filename = file.filename
  25. filename = os.path.basename(unsanitized_filename)
  26. # replace filename with uuid
  27. id = str(uuid.uuid4())
  28. name = filename
  29. filename = f"{id}_{filename}"
  30. file_path = f"{UPLOAD_DIR}/{filename}"
  31. contents = file.file.read()
  32. with open(file_path, "wb") as f:
  33. f.write(contents)
  34. f.close()
  35. file = Files.insert_new_file(
  36. user.id,
  37. FileForm(
  38. **{
  39. "id": id,
  40. "filename": filename,
  41. "meta": {
  42. "name": name,
  43. "content_type": file.content_type,
  44. "size": len(contents),
  45. "path": file_path,
  46. },
  47. }
  48. ),
  49. )
  50. if file:
  51. return file
  52. else:
  53. raise HTTPException(
  54. status_code=status.HTTP_400_BAD_REQUEST,
  55. detail=ERROR_MESSAGES.DEFAULT("Error uploading file"),
  56. )
  57. except Exception as e:
  58. log.exception(e)
  59. raise HTTPException(
  60. status_code=status.HTTP_400_BAD_REQUEST,
  61. detail=ERROR_MESSAGES.DEFAULT(e),
  62. )
  63. ############################
  64. # List Files
  65. ############################
  66. @router.get("/", response_model=list[FileModel])
  67. async def list_files(user=Depends(get_verified_user)):
  68. if user.role == "admin":
  69. files = Files.get_files()
  70. else:
  71. files = Files.get_files_by_user_id(user.id)
  72. return files
  73. ############################
  74. # Delete All Files
  75. ############################
  76. @router.delete("/all")
  77. async def delete_all_files(user=Depends(get_admin_user)):
  78. result = Files.delete_all_files()
  79. if result:
  80. folder = f"{UPLOAD_DIR}"
  81. try:
  82. # Check if the directory exists
  83. if os.path.exists(folder):
  84. # Iterate over all the files and directories in the specified directory
  85. for filename in os.listdir(folder):
  86. file_path = os.path.join(folder, filename)
  87. try:
  88. if os.path.isfile(file_path) or os.path.islink(file_path):
  89. os.unlink(file_path) # Remove the file or link
  90. elif os.path.isdir(file_path):
  91. shutil.rmtree(file_path) # Remove the directory
  92. except Exception as e:
  93. print(f"Failed to delete {file_path}. Reason: {e}")
  94. else:
  95. print(f"The directory {folder} does not exist")
  96. except Exception as e:
  97. print(f"Failed to process the directory {folder}. Reason: {e}")
  98. return {"message": "All files deleted successfully"}
  99. else:
  100. raise HTTPException(
  101. status_code=status.HTTP_400_BAD_REQUEST,
  102. detail=ERROR_MESSAGES.DEFAULT("Error deleting files"),
  103. )
  104. ############################
  105. # Get File By Id
  106. ############################
  107. @router.get("/{id}", response_model=Optional[FileModel])
  108. async def get_file_by_id(id: str, user=Depends(get_verified_user)):
  109. file = Files.get_file_by_id(id)
  110. if file and (file.user_id == user.id or user.role == "admin"):
  111. return file
  112. else:
  113. raise HTTPException(
  114. status_code=status.HTTP_404_NOT_FOUND,
  115. detail=ERROR_MESSAGES.NOT_FOUND,
  116. )
  117. ############################
  118. # Get File Content By Id
  119. ############################
  120. @router.get("/{id}/content", response_model=Optional[FileModel])
  121. async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
  122. file = Files.get_file_by_id(id)
  123. if file and (file.user_id == user.id or user.role == "admin"):
  124. file_path = Path(file.meta["path"])
  125. # Check if the file already exists in the cache
  126. if file_path.is_file():
  127. print(f"file_path: {file_path}")
  128. return FileResponse(file_path)
  129. else:
  130. raise HTTPException(
  131. status_code=status.HTTP_404_NOT_FOUND,
  132. detail=ERROR_MESSAGES.NOT_FOUND,
  133. )
  134. else:
  135. raise HTTPException(
  136. status_code=status.HTTP_404_NOT_FOUND,
  137. detail=ERROR_MESSAGES.NOT_FOUND,
  138. )
  139. @router.get("/{id}/content/{file_name}", response_model=Optional[FileModel])
  140. async def get_file_content_by_id(id: str, user=Depends(get_verified_user)):
  141. file = Files.get_file_by_id(id)
  142. if file and (file.user_id == user.id or user.role == "admin"):
  143. file_path = Path(file.meta["path"])
  144. # Check if the file already exists in the cache
  145. if file_path.is_file():
  146. print(f"file_path: {file_path}")
  147. return FileResponse(file_path)
  148. else:
  149. raise HTTPException(
  150. status_code=status.HTTP_404_NOT_FOUND,
  151. detail=ERROR_MESSAGES.NOT_FOUND,
  152. )
  153. else:
  154. raise HTTPException(
  155. status_code=status.HTTP_404_NOT_FOUND,
  156. detail=ERROR_MESSAGES.NOT_FOUND,
  157. )
  158. ############################
  159. # Delete File By Id
  160. ############################
  161. @router.delete("/{id}")
  162. async def delete_file_by_id(id: str, user=Depends(get_verified_user)):
  163. file = Files.get_file_by_id(id)
  164. if file and (file.user_id == user.id or user.role == "admin"):
  165. result = Files.delete_file_by_id(id)
  166. if result:
  167. return {"message": "File deleted successfully"}
  168. else:
  169. raise HTTPException(
  170. status_code=status.HTTP_400_BAD_REQUEST,
  171. detail=ERROR_MESSAGES.DEFAULT("Error deleting file"),
  172. )
  173. else:
  174. raise HTTPException(
  175. status_code=status.HTTP_404_NOT_FOUND,
  176. detail=ERROR_MESSAGES.NOT_FOUND,
  177. )