| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- from sqlalchemy import Column, String, Float, DateTime, Integer, Text, Boolean
- from sqlalchemy.ext.declarative import declarative_base
- from sqlalchemy.sql import func
- from datetime import datetime
- Base = declarative_base()
- class Book(Base):
- """Book information from Audiobookshelf."""
- __tablename__ = "books"
- id = Column(String, primary_key=True) # Audiobookshelf book ID
- title = Column(String, nullable=False)
- author = Column(String)
- narrator = Column(String)
- description = Column(Text)
- genres = Column(String) # JSON string of genres
- tags = Column(String) # JSON string of tags
- duration = Column(Float) # Duration in seconds
- cover_url = Column(String)
- created_at = Column(DateTime, default=func.now())
- updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
- class ListeningSession(Base):
- """User listening sessions and progress."""
- __tablename__ = "listening_sessions"
- id = Column(Integer, primary_key=True, autoincrement=True)
- book_id = Column(String, nullable=False)
- # Progress tracking
- progress = Column(Float, default=0.0) # 0.0 to 1.0
- current_time = Column(Float, default=0.0) # Current position in seconds
- is_finished = Column(Boolean, default=False)
- # Timestamps
- started_at = Column(DateTime)
- finished_at = Column(DateTime, nullable=True)
- last_update = Column(DateTime, default=func.now(), onupdate=func.now())
- # Ratings and preferences
- rating = Column(Integer, nullable=True) # 1-5 stars, optional
- class Recommendation(Base):
- """AI-generated book recommendations."""
- __tablename__ = "recommendations"
- id = Column(Integer, primary_key=True, autoincrement=True)
- # Recommendation details
- title = Column(String, nullable=False)
- author = Column(String)
- description = Column(Text)
- reason = Column(Text) # Why this book was recommended
- # Metadata
- genres = Column(String) # JSON string
- created_at = Column(DateTime, default=func.now())
- dismissed = Column(Boolean, default=False)
|