152 lines
3.5 KiB
Python
152 lines
3.5 KiB
Python
from datetime import date, datetime
|
|
|
|
from pydantic import BaseModel, field_validator
|
|
|
|
|
|
READING_STATUSES = {"reading", "finished", "paused", "wishlist"}
|
|
NOTE_VISIBILITIES = {"class", "private"}
|
|
|
|
|
|
class ReadingBookCreate(BaseModel):
|
|
title: str
|
|
author: str | None = None
|
|
cover_url: str | None = None
|
|
total_pages: int = 0
|
|
current_page: int = 0
|
|
status: str = "reading"
|
|
started_at: date | None = None
|
|
finished_at: date | None = None
|
|
personal_note: str | None = None
|
|
|
|
@field_validator("status")
|
|
@classmethod
|
|
def validate_status(cls, value: str) -> str:
|
|
if value not in READING_STATUSES:
|
|
raise ValueError("Invalid reading status")
|
|
return value
|
|
|
|
|
|
class ReadingBookUpdate(BaseModel):
|
|
title: str | None = None
|
|
author: str | None = None
|
|
cover_url: str | None = None
|
|
total_pages: int | None = None
|
|
current_page: int | None = None
|
|
status: str | None = None
|
|
started_at: date | None = None
|
|
finished_at: date | None = None
|
|
personal_note: str | None = None
|
|
|
|
@field_validator("status")
|
|
@classmethod
|
|
def validate_status(cls, value: str | None) -> str | None:
|
|
if value is not None and value not in READING_STATUSES:
|
|
raise ValueError("Invalid reading status")
|
|
return value
|
|
|
|
|
|
class ReadingBookOut(BaseModel):
|
|
id: int
|
|
class_id: int
|
|
owner_id: int
|
|
owner_name: str
|
|
title: str
|
|
author: str | None
|
|
cover_url: str | None
|
|
total_pages: int
|
|
current_page: int
|
|
status: str
|
|
started_at: date | None
|
|
finished_at: date | None
|
|
personal_note: str | None
|
|
note_count: int
|
|
public_note_count: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class ReadingNoteCreate(BaseModel):
|
|
title: str
|
|
content: str
|
|
page_ref: str | None = None
|
|
visibility: str = "class"
|
|
|
|
@field_validator("visibility")
|
|
@classmethod
|
|
def validate_visibility(cls, value: str) -> str:
|
|
if value not in NOTE_VISIBILITIES:
|
|
raise ValueError("Invalid note visibility")
|
|
return value
|
|
|
|
|
|
class ReadingNoteUpdate(BaseModel):
|
|
title: str | None = None
|
|
content: str | None = None
|
|
page_ref: str | None = None
|
|
visibility: str | None = None
|
|
|
|
@field_validator("visibility")
|
|
@classmethod
|
|
def validate_visibility(cls, value: str | None) -> str | None:
|
|
if value is not None and value not in NOTE_VISIBILITIES:
|
|
raise ValueError("Invalid note visibility")
|
|
return value
|
|
|
|
|
|
class ReadingNoteOut(BaseModel):
|
|
id: int
|
|
book_id: int
|
|
book_title: str
|
|
book_author: str | None
|
|
author_id: int
|
|
author_name: str
|
|
title: str
|
|
content: str
|
|
page_ref: str | None
|
|
visibility: str
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
|
|
class ReadingSummary(BaseModel):
|
|
reading_count: int
|
|
finished_count: int
|
|
total_pages_read: int
|
|
month_score: int
|
|
|
|
|
|
class ReadingRankingItem(BaseModel):
|
|
user_id: int
|
|
user_name: str
|
|
score: int
|
|
pages_read: int
|
|
finished_books: int
|
|
public_notes: int
|
|
private_notes: int
|
|
|
|
|
|
class ReadingRankingResponse(BaseModel):
|
|
period: str
|
|
items: list[ReadingRankingItem]
|
|
|
|
|
|
class ReadingFeedItem(BaseModel):
|
|
id: str
|
|
type: str
|
|
class_id: int
|
|
user_id: int
|
|
user_name: str
|
|
book_id: int
|
|
book_title: str
|
|
book_author: str | None
|
|
book_cover_url: str | None
|
|
status: str
|
|
current_page: int
|
|
total_pages: int
|
|
progress: int
|
|
note_id: int | None = None
|
|
note_title: str | None = None
|
|
note_excerpt: str | None = None
|
|
page_ref: str | None = None
|
|
created_at: datetime
|