foxfiles/foxfiles/blueprints/api/files.py
2024-02-13 02:23:21 +01:00

77 lines
1.9 KiB
Python

# SPDX-License-Identifier: Apache-2.0
from flask import Blueprint, g
from flask_pydantic import validate
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.orm import Session
from foxfiles.db import File, engine
from foxfiles.errors import Errors
from foxfiles.files import delete_file
from foxfiles.user import maybe_token, require_user
from foxfiles.settings import BASE_URL
bp = Blueprint("files_api", __name__)
class ListFilesQuery(BaseModel):
before: int | None = None
after: int | None = None
search: str | None = None
class ListFilesResponse(BaseModel):
id: int
url_id: str
filename: str
hash: str
content_type: str
url: str
@bp.get("/api/files")
@maybe_token
@require_user
@validate()
def list_files(query: ListFilesQuery):
stmt = (
select(File).where(File.user_id == g.user.id).limit(50).order_by(File.id.desc())
)
if query.before:
stmt = stmt.where(File.id < query.before)
if query.after:
stmt = stmt.where(File.id > query.after)
if query.search:
stmt = stmt.where(File.filename.like(f"%{query.search}%"))
with Session(engine) as session:
files = session.scalars(stmt)
return [
ListFilesResponse(
id=file.id,
url_id=file.url_id,
filename=file.filename,
hash=file.hash,
content_type=file.content_type,
url=f"{BASE_URL}/{file.path}",
).model_dump()
for file in files
]
@bp.delete("/api/files/<id>")
@maybe_token
@require_user
@validate()
def delete(id: int):
with Session(engine) as session:
file = session.scalar(select(File).where(File.id == id))
if not file or g.user.id != file.user_id:
return Errors.FILE_NOT_FOUND
session.delete(file)
session.commit()
delete_file(file.hash, file.content_type)
return "", 204