You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
4.3 KiB

7 months ago
8 months ago
7 months ago
8 months ago
7 months ago
8 months ago
8 months ago
8 months ago
7 months ago
8 months ago
7 months ago
8 months ago
  1. from fastapi import FastAPI, File, UploadFile, HTTPException, Form,Request
  2. import paramiko
  3. from fastapi import Depends, APIRouter, status, Query, Path, HTTPException
  4. from internal.models import *
  5. from internal.database import fetch_one, fetch_all, execute_query, response_success, raise_if_exists, raise_if_not_found
  6. from dependencies import get_current_active_user
  7. from datetime import datetime
  8. import os
  9. from pathlib import Path
  10. from limiter_config import limiter
  11. router = APIRouter(
  12. prefix="/photos",
  13. tags=['图片管理']
  14. )
  15. app = FastAPI()
  16. # 配置远程服务器信息
  17. REMOTE_HOST = "www.wuruilin.cn"
  18. REMOTE_PORT = 6000 # 默认为 22
  19. REMOTE_USERNAME = "root"
  20. REMOTE_PASSWORD = "zl981023"
  21. REMOTE_BASE_DIRECTORY = "/home/blog/imgs"
  22. def file_exists(sftp, remote_file_path: str) -> bool:
  23. """检查远程文件是否存在"""
  24. try:
  25. sftp.stat(remote_file_path)
  26. return True
  27. except FileNotFoundError:
  28. return False
  29. def ensure_remote_directory(sftp, remote_directory: str):
  30. """确保远程目录存在"""
  31. try:
  32. sftp.chdir(remote_directory) # 目录存在
  33. except IOError:
  34. sftp.mkdir(remote_directory) # 目录不存在,创建
  35. sftp.chdir(remote_directory)
  36. def list_files_in_remote_directory(sftp, remote_directory):
  37. try:
  38. file_list = sftp.listdir(remote_directory)
  39. return file_list
  40. except Exception as e:
  41. raise HTTPException(
  42. status_code=500, detail=f"Could not list files in remote directory: {e}")
  43. @router.post("/uploadfile/")
  44. @limiter.limit("10/minute")
  45. async def upload_file(request: Request,file: UploadFile = File(...), album_key: str = Form(...), new_filename: str = None):
  46. try:
  47. # 获取文件扩展名
  48. file_extension = os.path.splitext(file.filename)[1]
  49. # 使用原文件名,如果没有提供新的文件名
  50. if not new_filename:
  51. new_filename = file.filename
  52. # 保持扩展名
  53. if not new_filename.endswith(file_extension):
  54. new_filename += file_extension
  55. # 根据相册的 key 生成远程文件路径
  56. remote_directory = Path(REMOTE_BASE_DIRECTORY) / album_key
  57. remote_file_path = remote_directory / new_filename
  58. remote_file_path = remote_file_path.as_posix()
  59. # 使用 Paramiko 连接远程服务器
  60. ssh = paramiko.SSHClient()
  61. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  62. ssh.connect(REMOTE_HOST, port=REMOTE_PORT,
  63. username=REMOTE_USERNAME, password=REMOTE_PASSWORD)
  64. sftp = ssh.open_sftp()
  65. # 确保远程目录存在
  66. ensure_remote_directory(sftp, remote_directory.as_posix())
  67. # 检查文件是否存在,如果存在,返回错误消息
  68. if file_exists(sftp, remote_file_path):
  69. sftp.close()
  70. ssh.close()
  71. raise HTTPException(
  72. status_code=400, detail="File with the given name already exists in the album.")
  73. # 将文件对象直接上传到远程服务器
  74. sftp.putfo(file.file, remote_file_path)
  75. sftp.close()
  76. ssh.close()
  77. return {"filename": new_filename, "message": "File uploaded successfully"}
  78. except Exception as e:
  79. raise HTTPException(
  80. status_code=500, detail=f"Could not upload file to remote server: {e}")
  81. @router.get("/listfiles/")
  82. @limiter.limit("10/minute")
  83. async def list_files(request: Request,album_key: str):
  84. try:
  85. remote_directory = Path(REMOTE_BASE_DIRECTORY) / album_key
  86. remote_directory = remote_directory.as_posix()
  87. # 使用 Paramiko 连接远程服务器
  88. ssh = paramiko.SSHClient()
  89. ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  90. ssh.connect(REMOTE_HOST, port=REMOTE_PORT, username=REMOTE_USERNAME, password=REMOTE_PASSWORD)
  91. sftp = ssh.open_sftp()
  92. # 获取远程目录中的文件列表
  93. file_list = list_files_in_remote_directory(sftp, remote_directory)
  94. sftp.close()
  95. ssh.close()
  96. # 构造文件URL列表
  97. file_urls = [f"{album_key}/{filename}" for filename in file_list]
  98. return {"files": file_urls}
  99. except Exception as e:
  100. raise HTTPException(status_code=500, detail=f"Could not retrieve file list: {e}")