3 changed files with 126 additions and 3 deletions
@ -0,0 +1,124 @@ |
|||
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}") |
Write
Preview
Loading…
Cancel
Save
Reference in new issue