Init
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import secrets
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from sqlalchemy import delete, select, update
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.models import Wrap, WrapStatus
|
||||
from app.services.client_ip import client_ip, request_meta
|
||||
from app.services.storage import storage
|
||||
|
||||
|
||||
def new_wrap_id() -> str:
|
||||
return secrets.token_urlsafe(18).replace("-", "").replace("_", "")[:24]
|
||||
|
||||
|
||||
async def expire_due_wraps(db: AsyncSession) -> int:
|
||||
now = datetime.now(timezone.utc)
|
||||
result = await db.execute(
|
||||
select(Wrap).where(Wrap.status == WrapStatus.pending, Wrap.expires_at <= now)
|
||||
)
|
||||
rows = list(result.scalars().all())
|
||||
for wrap in rows:
|
||||
try:
|
||||
await storage.delete(wrap.object_key)
|
||||
except Exception:
|
||||
pass
|
||||
wrap.status = WrapStatus.expired
|
||||
if rows:
|
||||
await db.commit()
|
||||
return len(rows)
|
||||
|
||||
|
||||
async def delete_wrap_object(db: AsyncSession, wrap: Wrap) -> None:
|
||||
try:
|
||||
await storage.delete(wrap.object_key)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
async def cleanup_expired_meta(db: AsyncSession) -> int:
|
||||
"""Remove long-expired wrap rows (objects already deleted)."""
|
||||
now = datetime.now(timezone.utc)
|
||||
result = await db.execute(
|
||||
delete(Wrap).where(
|
||||
Wrap.status.in_([WrapStatus.expired, WrapStatus.consumed]),
|
||||
Wrap.expires_at < now,
|
||||
)
|
||||
)
|
||||
await db.commit()
|
||||
return result.rowcount or 0
|
||||
|
||||
|
||||
async def mark_consumed(db: AsyncSession, wrap_id: str) -> Wrap | None:
|
||||
now = datetime.now(timezone.utc)
|
||||
result = await db.execute(
|
||||
update(Wrap)
|
||||
.where(Wrap.id == wrap_id, Wrap.status == WrapStatus.pending, Wrap.expires_at > now)
|
||||
.values(status=WrapStatus.consumed, consumed_at=now)
|
||||
.returning(Wrap)
|
||||
)
|
||||
row = result.scalar_one_or_none()
|
||||
await db.commit()
|
||||
return row
|
||||
|
||||
|
||||
async def purge_all_wraps(db: AsyncSession) -> dict[str, int]:
|
||||
"""Force-delete all wrap DB rows and all objects under wraps/ in MinIO."""
|
||||
count_result = await db.execute(select(Wrap.id))
|
||||
db_count = len(list(count_result.scalars().all()))
|
||||
await db.execute(delete(Wrap))
|
||||
await db.commit()
|
||||
objects_deleted = await storage.delete_prefix("wraps/")
|
||||
return {"wraps_deleted": db_count, "objects_deleted": objects_deleted}
|
||||
Reference in New Issue
Block a user