Files

130 lines
4.0 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func, delete
from app.core.database import get_db
from app.core.deps import get_approved_user
from app.models.user import User
from app.models.collection import CollectionCard
from app.schemas.collection import CollectionCardOut, CollectionStatsOut, PaginatedCollection
from app.services.imports import archidekt, manabox
from app.services.imports.enrichment import enrich_and_upsert
router = APIRouter()
@router.post("/import/archidekt", status_code=201)
async def import_archidekt(
file: UploadFile = File(...),
replace: bool = False,
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
raw = await file.read()
rows = archidekt.parse(raw)
if replace:
await db.execute(delete(CollectionCard).where(CollectionCard.owner_id == user.id))
await db.commit()
imported = await enrich_and_upsert(rows, user.id, db)
return {"imported": imported}
@router.post("/import/manabox", status_code=201)
async def import_manabox(
file: UploadFile = File(...),
replace: bool = False,
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
raw = await file.read()
rows = manabox.parse(raw)
if replace:
await db.execute(delete(CollectionCard).where(CollectionCard.owner_id == user.id))
await db.commit()
imported = await enrich_and_upsert(rows, user.id, db)
return {"imported": imported}
@router.get("/", response_model=PaginatedCollection)
async def list_collection(
search: str = "",
page: int = 1,
page_size: int = 50,
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
query = select(CollectionCard).where(CollectionCard.owner_id == user.id)
if search:
query = query.where(CollectionCard.card_name.ilike(f"%{search}%"))
total_result = await db.execute(
select(func.count()).select_from(query.subquery())
)
total = total_result.scalar_one()
result = await db.execute(
query.order_by(CollectionCard.card_name)
.offset((page - 1) * page_size)
.limit(page_size)
)
items = result.scalars().all()
return PaginatedCollection(
items=items, total=total, page=page, page_size=page_size,
pages=max(1, -(-total // page_size)),
)
@router.get("/stats", response_model=CollectionStatsOut)
async def collection_stats(
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(
select(CollectionCard).where(CollectionCard.owner_id == user.id)
)
cards = result.scalars().all()
total = sum(c.quantity + c.foil_quantity for c in cards)
unique = len(cards)
foil = sum(c.foil_quantity for c in cards)
value = None
prices = []
for c in cards:
if c.scryfall_data:
p = c.scryfall_data.get("prices", {}).get("usd")
if p:
prices.append(float(p) * (c.quantity + c.foil_quantity))
if prices:
value = sum(prices)
return CollectionStatsOut(
total_cards=total, unique_cards=unique, foil_cards=foil, estimated_value=value
)
@router.delete("/", status_code=204)
async def clear_collection(
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
await db.execute(delete(CollectionCard).where(CollectionCard.owner_id == user.id))
await db.commit()
@router.delete("/{card_id}", status_code=204)
async def delete_card(
card_id: int,
user: User = Depends(get_approved_user),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(
select(CollectionCard).where(CollectionCard.id == card_id, CollectionCard.owner_id == user.id)
)
card = result.scalar_one_or_none()
if not card:
raise HTTPException(status_code=404, detail="Card not found")
await db.delete(card)
await db.commit()