151 lines
4.2 KiB
Python
151 lines
4.2 KiB
Python
"""Synchronization routes for atproto"""
|
|
from fastapi import APIRouter, HTTPException, Depends
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from pydantic import BaseModel
|
|
|
|
from app.auth.dependencies import require_user, AuthUser
|
|
from app.db.base import get_db
|
|
from app.services.card_sync import CardSyncService
|
|
from app.repositories.user import UserRepository
|
|
|
|
|
|
router = APIRouter(prefix="/sync", tags=["sync"])
|
|
|
|
|
|
class SyncRequest(BaseModel):
|
|
"""Sync request model"""
|
|
atproto_session: str # Session string from atproto login
|
|
|
|
|
|
class SyncResponse(BaseModel):
|
|
"""Sync response model"""
|
|
synced_to_pds: int = 0
|
|
imported_from_pds: int = 0
|
|
message: str
|
|
|
|
|
|
@router.post("/cards", response_model=SyncResponse)
|
|
async def sync_cards(
|
|
request: SyncRequest,
|
|
current_user: AuthUser = Depends(require_user),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""
|
|
Sync cards between database and atproto PDS
|
|
|
|
- **atproto_session**: Session string from atproto login
|
|
"""
|
|
try:
|
|
# Get user from database
|
|
user_repo = UserRepository(db)
|
|
user = await user_repo.get_by_did(current_user.did)
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
# Create sync service
|
|
sync_service = CardSyncService(db, request.atproto_session)
|
|
|
|
# Import from PDS first
|
|
imported = await sync_service.import_cards_from_pds(current_user.did)
|
|
|
|
# Then sync all cards to PDS
|
|
synced = await sync_service.sync_all_user_cards(user.id, current_user.did)
|
|
|
|
await db.commit()
|
|
|
|
return SyncResponse(
|
|
synced_to_pds=synced,
|
|
imported_from_pds=imported,
|
|
message=f"Successfully synced {synced} cards to PDS and imported {imported} cards from PDS"
|
|
)
|
|
|
|
except Exception as e:
|
|
await db.rollback()
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.post("/export")
|
|
async def export_to_pds(
|
|
request: SyncRequest,
|
|
current_user: AuthUser = Depends(require_user),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""
|
|
Export all cards to atproto PDS
|
|
|
|
- **atproto_session**: Session string from atproto login
|
|
"""
|
|
try:
|
|
user_repo = UserRepository(db)
|
|
user = await user_repo.get_by_did(current_user.did)
|
|
if not user:
|
|
raise HTTPException(status_code=404, detail="User not found")
|
|
|
|
sync_service = CardSyncService(db, request.atproto_session)
|
|
synced = await sync_service.sync_all_user_cards(user.id, current_user.did)
|
|
|
|
return {
|
|
"exported": synced,
|
|
"message": f"Successfully exported {synced} cards to PDS"
|
|
}
|
|
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.post("/import")
|
|
async def import_from_pds(
|
|
request: SyncRequest,
|
|
current_user: AuthUser = Depends(require_user),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""
|
|
Import cards from atproto PDS
|
|
|
|
- **atproto_session**: Session string from atproto login
|
|
"""
|
|
try:
|
|
sync_service = CardSyncService(db, request.atproto_session)
|
|
imported = await sync_service.import_cards_from_pds(current_user.did)
|
|
|
|
await db.commit()
|
|
|
|
return {
|
|
"imported": imported,
|
|
"message": f"Successfully imported {imported} cards from PDS"
|
|
}
|
|
|
|
except Exception as e:
|
|
await db.rollback()
|
|
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
|
|
@router.get("/verify/{card_id}")
|
|
async def verify_card_ownership(
|
|
card_id: int,
|
|
unique_id: Optional[str] = None,
|
|
current_user: AuthUser = Depends(require_user),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""
|
|
Verify user owns a specific card
|
|
|
|
- **card_id**: Card type ID (0-15)
|
|
- **unique_id**: Unique ID for unique cards
|
|
"""
|
|
sync_service = CardSyncService(db)
|
|
owns_card = await sync_service.verify_card_ownership(
|
|
current_user.did,
|
|
card_id,
|
|
unique_id
|
|
)
|
|
|
|
return {
|
|
"card_id": card_id,
|
|
"unique_id": unique_id,
|
|
"owned": owns_card
|
|
}
|
|
|
|
|
|
# Import Optional
|
|
from typing import Optional |