Add Notification and new mini desing
This commit is contained in:
153
backend/main.py
153
backend/main.py
@@ -73,8 +73,8 @@ IS_WINDOWS = sys.platform == 'win32'
|
||||
def init_users():
|
||||
if not USERS_FILE.exists():
|
||||
admin_user = {
|
||||
"username": "Sofa12345",
|
||||
"password": pwd_context.hash("arkonsad123"),
|
||||
"username": "Root",
|
||||
"password": pwd_context.hash("Admin"),
|
||||
"role": "admin",
|
||||
"servers": []
|
||||
}
|
||||
@@ -1005,23 +1005,88 @@ async def download_file(server_name: str, path: str, user: dict = Depends(get_cu
|
||||
|
||||
@app.post("/api/servers/{server_name}/files/upload")
|
||||
async def upload_file(server_name: str, path: str, file: UploadFile = File(...), user: dict = Depends(get_current_user)):
|
||||
print(f"Upload request: server={server_name}, path='{path}', filename='{file.filename}'")
|
||||
|
||||
if not check_server_access(user, server_name):
|
||||
raise HTTPException(403, "Нет доступа к этому серверу")
|
||||
|
||||
server_path = SERVERS_DIR / server_name
|
||||
target_path = server_path / path / file.filename
|
||||
|
||||
print(f"Target path: {target_path}")
|
||||
print(f"Server path: {server_path}")
|
||||
print(f"Path starts with server_path: {str(target_path).startswith(str(server_path))}")
|
||||
|
||||
if not str(target_path).startswith(str(server_path)):
|
||||
raise HTTPException(400, "Недопустимый путь")
|
||||
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
target_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
print(f"Created directory: {target_path.parent}")
|
||||
except Exception as e:
|
||||
print(f"Error creating directory: {e}")
|
||||
raise HTTPException(500, f"Ошибка создания директории: {str(e)}")
|
||||
|
||||
with open(target_path, "wb") as f:
|
||||
content = await file.read()
|
||||
f.write(content)
|
||||
try:
|
||||
with open(target_path, "wb") as f:
|
||||
content = await file.read()
|
||||
f.write(content)
|
||||
print(f"File written successfully: {target_path}")
|
||||
except Exception as e:
|
||||
print(f"Error writing file: {e}")
|
||||
raise HTTPException(500, f"Ошибка записи файла: {str(e)}")
|
||||
|
||||
return {"message": "Файл загружен"}
|
||||
|
||||
@app.post("/api/servers/{server_name}/files/create")
|
||||
async def create_file_or_folder(server_name: str, data: dict, user: dict = Depends(get_current_user)):
|
||||
"""Создать новый файл или папку"""
|
||||
if not check_server_access(user, server_name):
|
||||
raise HTTPException(403, "Нет доступа к этому серверу")
|
||||
|
||||
item_type = data.get("type") # "file" or "folder"
|
||||
name = data.get("name", "").strip()
|
||||
path = data.get("path", "") # Текущая папка
|
||||
|
||||
if not name:
|
||||
raise HTTPException(400, "Имя не может быть пустым")
|
||||
|
||||
if item_type not in ["file", "folder"]:
|
||||
raise HTTPException(400, "Тип должен быть 'file' или 'folder'")
|
||||
|
||||
server_path = SERVERS_DIR / server_name
|
||||
|
||||
# Формируем полный путь
|
||||
if path:
|
||||
full_path = server_path / path / name
|
||||
else:
|
||||
full_path = server_path / name
|
||||
|
||||
print(f"Creating {item_type}: {full_path}")
|
||||
|
||||
# Проверка безопасности
|
||||
if not str(full_path).startswith(str(server_path)):
|
||||
raise HTTPException(400, "Недопустимый путь")
|
||||
|
||||
try:
|
||||
if item_type == "folder":
|
||||
# Создаем папку
|
||||
full_path.mkdir(parents=True, exist_ok=True)
|
||||
# Создаем .gitkeep чтобы папка не была пустой
|
||||
gitkeep = full_path / ".gitkeep"
|
||||
gitkeep.touch()
|
||||
print(f"Folder created: {full_path}")
|
||||
else:
|
||||
# Создаем файл
|
||||
full_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
full_path.touch()
|
||||
print(f"File created: {full_path}")
|
||||
|
||||
return {"message": f"{'Папка' if item_type == 'folder' else 'Файл'} создан(а)", "path": str(full_path)}
|
||||
except Exception as e:
|
||||
print(f"Error creating {item_type}: {e}")
|
||||
raise HTTPException(500, f"Ошибка создания: {str(e)}")
|
||||
|
||||
@app.delete("/api/servers/{server_name}/files")
|
||||
async def delete_file(server_name: str, path: str, user: dict = Depends(get_current_user)):
|
||||
if not check_server_access(user, server_name):
|
||||
@@ -1098,6 +1163,82 @@ async def rename_file(server_name: str, old_path: str, new_name: str, user: dict
|
||||
old_file_path.rename(new_file_path)
|
||||
return {"message": "Файл переименован"}
|
||||
|
||||
@app.post("/api/servers/{server_name}/files/move")
|
||||
async def move_file(server_name: str, data: dict, user: dict = Depends(get_current_user)):
|
||||
"""Переместить файл или папку"""
|
||||
if not check_server_access(user, server_name):
|
||||
raise HTTPException(403, "Нет доступа к этому серверу")
|
||||
|
||||
source_path = data.get("source", "").strip()
|
||||
destination_path = data.get("destination", "").strip()
|
||||
|
||||
if not source_path:
|
||||
raise HTTPException(400, "Не указан исходный путь")
|
||||
|
||||
server_path = SERVERS_DIR / server_name
|
||||
source_full = server_path / source_path
|
||||
|
||||
# Формируем путь назначения
|
||||
if destination_path:
|
||||
# Извлекаем имя файла из source_path
|
||||
file_name = source_full.name
|
||||
dest_full = server_path / destination_path / file_name
|
||||
else:
|
||||
# Перемещение в корень
|
||||
file_name = source_full.name
|
||||
dest_full = server_path / file_name
|
||||
|
||||
print(f"Moving: {source_full} -> {dest_full}")
|
||||
|
||||
# Проверки безопасности
|
||||
if not source_full.exists():
|
||||
raise HTTPException(404, "Исходный файл не найден")
|
||||
|
||||
if not str(source_full).startswith(str(server_path)):
|
||||
raise HTTPException(400, "Недопустимый исходный путь")
|
||||
|
||||
if not str(dest_full).startswith(str(server_path)):
|
||||
raise HTTPException(400, "Недопустимый путь назначения")
|
||||
|
||||
if dest_full.exists():
|
||||
raise HTTPException(400, "Файл с таким именем уже существует в папке назначения")
|
||||
|
||||
try:
|
||||
# Создаем папку назначения если не существует
|
||||
dest_full.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Перемещаем файл/папку
|
||||
import shutil
|
||||
shutil.move(str(source_full), str(dest_full))
|
||||
|
||||
print(f"Moved successfully: {dest_full}")
|
||||
return {"message": "Файл перемещен", "new_path": str(dest_full)}
|
||||
except Exception as e:
|
||||
print(f"Error moving file: {e}")
|
||||
raise HTTPException(500, f"Ошибка перемещения: {str(e)}")
|
||||
|
||||
@app.put("/api/servers/{server_name}/files/rename")
|
||||
async def rename_file(server_name: str, old_path: str, new_name: str, user: dict = Depends(get_current_user)):
|
||||
if not check_server_access(user, server_name):
|
||||
raise HTTPException(403, "Нет доступа к этому серверу")
|
||||
|
||||
server_path = SERVERS_DIR / server_name
|
||||
old_file_path = server_path / old_path
|
||||
|
||||
if not old_file_path.exists() or not str(old_file_path).startswith(str(server_path)):
|
||||
raise HTTPException(404, "Файл не найден")
|
||||
|
||||
new_file_path = old_file_path.parent / new_name
|
||||
|
||||
if new_file_path.exists():
|
||||
raise HTTPException(400, "Файл с таким именем уже существует")
|
||||
|
||||
if not str(new_file_path).startswith(str(server_path)):
|
||||
raise HTTPException(400, "Недопустимое имя файла")
|
||||
|
||||
old_file_path.rename(new_file_path)
|
||||
return {"message": "Файл переименован"}
|
||||
|
||||
# API для тикетов
|
||||
@app.get("/api/tickets")
|
||||
async def get_tickets(user: dict = Depends(get_current_user)):
|
||||
|
||||
Reference in New Issue
Block a user