77 lines
1.9 KiB
Python
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
|