diff --git a/dependencies.py b/dependencies.py index 04883b7..6d55d41 100644 --- a/dependencies.py +++ b/dependencies.py @@ -15,8 +15,6 @@ pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/users/token") # 创建访问令牌 - - def create_access_token(data: dict, expires_delta: timedelta): to_encode = data.copy() expire = datetime.now(timezone.utc) + expires_delta diff --git a/main.py b/main.py index 11575f9..5f42e07 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from fastapi import Depends, FastAPI, HTTPException, status from dependencies import * from internal.models import Token from fastapi.middleware.cors import CORSMiddleware -from routers import blogtype, usermanage,blogmanage,classticmanage,commonlinkmanage,labelmanage,diarymanage,diarytype,statistic,disbursemanage +from routers import blogtype, usermanage,blogmanage,classticmanage,commonlinkmanage,labelmanage,diarymanage,diarytype,statistic,disbursemanage,photomanage app=FastAPI() app.include_router(usermanage.router) app.include_router(blogtype.router) @@ -16,6 +16,7 @@ app.include_router(commonlinkmanage.router) app.include_router(labelmanage.router) app.include_router(statistic.router) app.include_router(disbursemanage.router) +app.include_router(photomanage.router) # 解决跨域 app.add_middleware( CORSMiddleware, diff --git a/routers/photomanage.py b/routers/photomanage.py new file mode 100644 index 0000000..b6c1880 --- /dev/null +++ b/routers/photomanage.py @@ -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}")