Add Notification and new mini desing

This commit is contained in:
2026-01-15 13:26:04 +06:00
parent 303d38f28e
commit 8edd7131a2
56 changed files with 3554 additions and 5197 deletions

View File

@@ -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)):