104 lines
3.2 KiB
Python
104 lines
3.2 KiB
Python
import uuid
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import BaseModel
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from ...auth import verify_token
|
|
from ...config import settings
|
|
from ...domain.services.article_service import ArticleService
|
|
from ...outbound.postgres.database import get_db
|
|
from ...outbound.postgres.repositories.translated_article_repository import TranslatedArticleRepository
|
|
|
|
router = APIRouter(prefix="/articles", tags=["bff", "articles"])
|
|
|
|
|
|
class ArticleItem(BaseModel):
|
|
id: str
|
|
published_at: datetime
|
|
source_language: str
|
|
source_title: str
|
|
target_language: str
|
|
target_complexities: list[str]
|
|
target_title: str
|
|
|
|
|
|
class ArticleListResponse(BaseModel):
|
|
articles: list[ArticleItem]
|
|
|
|
|
|
class ArticleDetail(BaseModel):
|
|
id: str
|
|
published_at: datetime
|
|
source_language: str
|
|
source_title: str
|
|
source_body: str
|
|
target_language: str
|
|
target_complexities: list[str]
|
|
target_title: str
|
|
target_body: str
|
|
target_audio_url: str | None
|
|
target_body_pos: dict | None
|
|
target_body_transcript: dict | None
|
|
|
|
|
|
def _audio_url(key: str | None) -> str | None:
|
|
if key is None:
|
|
return None
|
|
return f"{settings.api_base_url}/media/{key}"
|
|
|
|
|
|
@router.get("", response_model=ArticleListResponse, status_code=200)
|
|
async def list_articles(
|
|
target_language: str = 'fr',
|
|
db: AsyncSession = Depends(get_db),
|
|
_: dict = Depends(verify_token),
|
|
) -> ArticleListResponse:
|
|
service = ArticleService(TranslatedArticleRepository(db))
|
|
articles = await service.get_all_articles(target_language=target_language)
|
|
return ArticleListResponse(
|
|
articles=[
|
|
ArticleItem(
|
|
id=a.id,
|
|
published_at=a.published_at,
|
|
source_language=a.source_language,
|
|
source_title=a.source_title,
|
|
target_language=a.target_language,
|
|
target_complexities=a.target_complexities,
|
|
target_title=a.target_title,
|
|
)
|
|
for a in articles
|
|
]
|
|
)
|
|
|
|
|
|
@router.get("/{article_id}", response_model=ArticleDetail, status_code=200)
|
|
async def get_article(
|
|
article_id: str,
|
|
db: AsyncSession = Depends(get_db),
|
|
_: dict = Depends(verify_token),
|
|
) -> ArticleDetail:
|
|
try:
|
|
uid = uuid.UUID(article_id)
|
|
except ValueError:
|
|
raise HTTPException(status_code=400, detail="Invalid article ID")
|
|
|
|
article = await TranslatedArticleRepository(db).get_by_id(uid)
|
|
if article is None:
|
|
raise HTTPException(status_code=404, detail="Article not found")
|
|
|
|
return ArticleDetail(
|
|
id=article.id,
|
|
published_at=article.published_at,
|
|
source_language=article.source_language,
|
|
source_title=article.source_title,
|
|
source_body=article.source_body,
|
|
target_language=article.target_language,
|
|
target_complexities=article.target_complexities,
|
|
target_title=article.target_title,
|
|
target_body=article.target_body,
|
|
target_audio_url=_audio_url(article.audio_url),
|
|
target_body_pos=article.target_body_pos,
|
|
target_body_transcript=article.target_body_transcript,
|
|
)
|