|
|
from fastapi import FastAPI, File, UploadFile, HTTPException, Form import paramiko from fastapi import Depends, APIRouter, status, Query, Path, HTTPException from internal.models import * from internal.database import fetch_one, fetch_all, execute_query, response_success, raise_if_exists, raise_if_not_found from dependencies import get_current_active_user from datetime import datetime import os from pathlib import Path router = APIRouter( prefix="/photos", tags=['图片管理'] )
app = FastAPI()
# 配置远程服务器信息 REMOTE_HOST = "111.229.38.129" REMOTE_PORT = 6000 # 默认为 22 REMOTE_USERNAME = "root" REMOTE_PASSWORD = "zl981023" REMOTE_BASE_DIRECTORY = "/home/blog"
def file_exists(sftp, remote_file_path: str) -> bool: """检查远程文件是否存在""" try: sftp.stat(remote_file_path) return True except FileNotFoundError: return False
def ensure_remote_directory(sftp, remote_directory: str): """确保远程目录存在""" try: sftp.chdir(remote_directory) # 目录存在 except IOError: sftp.mkdir(remote_directory) # 目录不存在,创建 sftp.chdir(remote_directory)
def list_files_in_remote_directory(sftp, remote_directory): try: file_list = sftp.listdir(remote_directory) return file_list except Exception as e: raise HTTPException( status_code=500, detail=f"Could not list files in remote directory: {e}")
@router.post("/uploadfile/") async def upload_file(file: UploadFile = File(...), album_key: str = Form(...), new_filename: str = None): try: # 获取文件扩展名 file_extension = os.path.splitext(file.filename)[1]
# 使用原文件名,如果没有提供新的文件名 if not new_filename: new_filename = file.filename
# 保持扩展名 if not new_filename.endswith(file_extension): new_filename += file_extension
# 根据相册的 key 生成远程文件路径 remote_directory = Path(REMOTE_BASE_DIRECTORY) / album_key remote_file_path = remote_directory / new_filename remote_file_path = remote_file_path.as_posix()
# 使用 Paramiko 连接远程服务器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(REMOTE_HOST, port=REMOTE_PORT, username=REMOTE_USERNAME, password=REMOTE_PASSWORD)
sftp = ssh.open_sftp()
# 确保远程目录存在 ensure_remote_directory(sftp, remote_directory.as_posix())
# 检查文件是否存在,如果存在,返回错误消息 if file_exists(sftp, remote_file_path): sftp.close() ssh.close() raise HTTPException( status_code=400, detail="File with the given name already exists in the album.")
# 将文件对象直接上传到远程服务器 sftp.putfo(file.file, remote_file_path) sftp.close() ssh.close()
return {"filename": new_filename, "message": "File uploaded successfully"} except Exception as e: raise HTTPException( status_code=500, detail=f"Could not upload file to remote server: {e}")
@router.get("/listfiles/") async def list_files(album_key: str): try: remote_directory = Path(REMOTE_BASE_DIRECTORY) / album_key remote_directory = remote_directory.as_posix() # 使用 Paramiko 连接远程服务器 ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(REMOTE_HOST, port=REMOTE_PORT, username=REMOTE_USERNAME, password=REMOTE_PASSWORD) sftp = ssh.open_sftp() # 获取远程目录中的文件列表 file_list = list_files_in_remote_directory(sftp, remote_directory) sftp.close() ssh.close() # 构造文件URL列表 file_urls = [f"{album_key}/{filename}" for filename in file_list] return {"files": file_urls} except Exception as e: raise HTTPException(status_code=500, detail=f"Could not retrieve file list: {e}")
|