75 lines
3.0 KiB
Python
Raw Normal View History

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")