144 lines
3.8 KiB
Python
144 lines
3.8 KiB
Python
from fastapi import HTTPException
|
|
from sqlalchemy import select
|
|
from sqlalchemy.exc import SQLAlchemyError
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy.orm import joinedload
|
|
|
|
from models.library import LibraryFile, Subject, Module
|
|
from schemas.library import LibraryFileRequest, LibraryFileResponse
|
|
|
|
|
|
async def list_files(db: AsyncSession) -> list[LibraryFileResponse]:
|
|
stmt = (
|
|
select(LibraryFile)
|
|
.options(
|
|
joinedload(LibraryFile.subject),
|
|
joinedload(LibraryFile.module),
|
|
)
|
|
.order_by(LibraryFile.create_time.desc())
|
|
)
|
|
|
|
files = (await db.execute(stmt)).scalars().unique().all()
|
|
|
|
return [
|
|
LibraryFileResponse(
|
|
id=file.id,
|
|
subject=file.subject.name,
|
|
module=file.module.name,
|
|
name=file.name,
|
|
type=file.type,
|
|
size=file.size,
|
|
content=file.content,
|
|
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
)
|
|
for file in files
|
|
]
|
|
|
|
|
|
async def add_file(db: AsyncSession, data: LibraryFileRequest) -> bool:
|
|
try:
|
|
subject_id = await get_or_create_subject(db, data.subject)
|
|
module_id = await get_or_create_module(db, subject_id, data.module)
|
|
|
|
file = LibraryFile(
|
|
subject_id=subject_id,
|
|
module_id=module_id,
|
|
name=data.name,
|
|
size=data.size,
|
|
type=data.type,
|
|
content=data.content,
|
|
)
|
|
|
|
db.add(file)
|
|
await db.commit()
|
|
return True
|
|
|
|
except SQLAlchemyError:
|
|
await db.rollback()
|
|
raise
|
|
|
|
|
|
async def edit_file(db: AsyncSession, file_id: int, data: LibraryFileRequest) -> bool:
|
|
try:
|
|
result = await db.execute(
|
|
select(LibraryFile).where(LibraryFile.id == file_id)
|
|
)
|
|
file = result.scalar_one_or_none()
|
|
if not file:
|
|
return False
|
|
|
|
subject_id = await get_or_create_subject(db, data.subject)
|
|
module_id = await get_or_create_module(db, subject_id, data.module)
|
|
|
|
file.subject_id = subject_id
|
|
file.module_id = module_id
|
|
file.name = data.name
|
|
file.size = data.size
|
|
file.type = data.type
|
|
file.content = data.content
|
|
|
|
await db.commit()
|
|
return True
|
|
|
|
except SQLAlchemyError:
|
|
await db.rollback()
|
|
raise
|
|
|
|
|
|
async def get_file(db: AsyncSession, file_id: int) -> LibraryFileResponse:
|
|
stmt = (
|
|
select(LibraryFile)
|
|
.options(
|
|
joinedload(LibraryFile.subject),
|
|
joinedload(LibraryFile.module),
|
|
)
|
|
.where(LibraryFile.id == file_id)
|
|
)
|
|
|
|
file = (await db.execute(stmt)).scalar_one_or_none()
|
|
if not file:
|
|
raise HTTPException(status_code=404, detail="File not found")
|
|
|
|
return LibraryFileResponse(
|
|
id=file.id,
|
|
subject=file.subject.name,
|
|
module=file.module.name,
|
|
name=file.name,
|
|
type=file.type,
|
|
size=file.size,
|
|
content=file.content,
|
|
uploadTime=file.create_time.strftime("%Y-%m-%d %H:%M:%S"),
|
|
)
|
|
|
|
|
|
async def get_or_create_subject(db: AsyncSession, name: str) -> int:
|
|
stmt = select(Subject).where(Subject.name == name)
|
|
result = await db.execute(stmt)
|
|
subject = result.scalar_one_or_none()
|
|
|
|
if subject:
|
|
return subject.id
|
|
|
|
subject = Subject(name=name)
|
|
db.add(subject)
|
|
await db.flush()
|
|
|
|
return subject.id
|
|
|
|
|
|
async def get_or_create_module(db: AsyncSession, subject_id: int, name: str) -> int:
|
|
stmt = select(Module).where(
|
|
Module.subject_id == subject_id,
|
|
Module.name == name,
|
|
)
|
|
module = (await db.execute(stmt)).scalar_one_or_none()
|
|
|
|
if module:
|
|
return module.id
|
|
|
|
module = Module(subject_id=subject_id, name=name)
|
|
db.add(module)
|
|
await db.flush()
|
|
|
|
return module.id
|