L-Nafaryus 997f37d5ee
new: reconstruct project
new: pdm package manager (python)
new: workspace for three subprojects
new: dream2nix module for packaging
new: postgresql and redis images
more: and more
2024-06-17 19:52:24 +05:00

75 lines
3.0 KiB
Python

import os
import time
from pathlib import Path
from fastapi import APIRouter, Depends, HTTPException, Request, UploadFile, status
from fastapi.responses import StreamingResponse
from sqlalchemy import and_, insert, select, update
from materia import db
from materia.api.state import ConfigState, DatabaseState
from materia.api.middleware import JwtMiddleware
from materia.config import Config
from materia.api import schema
router = APIRouter(tags = ["directory"])
@router.post("/directory", dependencies = [Depends(JwtMiddleware())])
async def create(request: Request, path: Path = Path(), config: ConfigState = Depends(), database: DatabaseState = Depends()):
user = request.state.user
repository_path = Config.data_dir() / "repository" / user.login_name.lower()
blacklist = [os.sep, ".", "..", "*"]
directory_path = Path(os.sep.join(filter(lambda part: part not in blacklist, path.parts)))
async with database.session() as session:
session.add(user)
await session.refresh(user, attribute_names = ["repository"])
current_directory = None
current_path = Path()
directory = None
for part in directory_path.parts:
if not (directory := (await session
.scalars(select(db.Directory)
.where(and_(db.Directory.name == part, db.Directory.path == str(current_path))))
).first()):
directory = db.Directory(
repository_id = user.repository.id,
parent_id = current_directory.id if current_directory else None,
name = part,
path = str(current_path)
)
session.add(directory)
current_directory = directory
current_path /= part
try:
(repository_path / directory_path).mkdir(parents = True, exist_ok = True)
except OSError:
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR, "Failed to created a directory")
await session.commit()
@router.get("/directory", dependencies = [Depends(JwtMiddleware())])
async def info(request: Request, repository_id: int, path: Path, config: ConfigState = Depends(), database: DatabaseState = Depends()):
async with database.session() as session:
if directory := (await session
.scalars(select(db.Directory)
.where(and_(db.Directory.repository_id == repository_id, db.Directory.name == path.name, db.Directory.path == path.parent))
)).first():
await session.refresh(directory, attribute_names = ["files"])
return schema.DirectoryInfo(
id = directory.id,
created_at = directory.created_unix,
updated_at = directory.updated_unix,
name = directory.name,
path = directory.path,
is_public = directory.is_public,
used = sum([ file.size for file in directory.files ])
)
else:
raise HTTPException(status.HTTP_404_NOT_FOUND, "Repository is not found")