class Base(db.Model): __abstract__ = True id = db.Column(db.Integer(), primary_key=True, autoincrement=True, nullable=False) created_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), nullable=False) updated_at = db.Column(db.DateTime(timezone=True), onupdate=func.now(), nullable=True) def __repr__(self): return f'<{self.__class__} {self.id}>: {self.__dict__}' @classmethod def create(cls, **kwargs) -> T: model = cls(**kwargs) db.session.add(model) db.session.commit() return model def save(self) -> T: self.updated_at = datetime.utcnow() db.session.add(self) db.session.commit() return self def delete(self) -> T: db.session.delete(self) db.session.commit() return self
class Flashcard(Base): __tablename__ = 'flashcards' language_id = db.Column(db.Integer(), ForeignKey(Language.id), nullable=True) standard_deck_id = db.Column(db.Integer(), ForeignKey(StandardDeck.id), nullable=True) user_deck_id = db.Column(db.Integer(), ForeignKey(UserDeck.id, ondelete='CASCADE'), nullable=True) user_id = db.Column(db.Integer(), ForeignKey(User.id, ondelete='CASCADE'), nullable=True) front = db.Column(db.String(1024), nullable=False) back = db.Column(db.String(1024), nullable=False) rank = db.Column(db.Integer(), nullable=True) audio_url = db.Column(db.String(1024), nullable=True) refresh_at = db.Column(db.DateTime(timezone=True), nullable=True) @classmethod def create_from_user_data( cls, user: User, language: Language, front: str, back: Optional[str] = None, rank: Optional[int] = None, audio_url: Optional[str] = None, user_deck_id: Optional[int] = None, ) -> 'Flashcard': # TODO: support translating to languages other than English if back is None: back = translate_text(front, 'en') if audio_url is None: audio_url = create_and_store_tts(front, language.locale) if user_deck_id is None: user_deck_id = UserDeck.query.filter_by( user_id=user.id, name=default_deck_name).scalar().id flashcard = Flashcard.create( language_id=language.id, user_deck_id=user_deck_id, user_id=user.id, front=front, back=back, rank=rank, audio_url=audio_url, refresh_at=datetime.utcnow(), ) return flashcard
class ForkedUserDeck(Base): __tablename__ = 'forked_user_decks' name = db.Column(db.String(256), nullable=False) user_id = db.Column(db.Integer(), ForeignKey(User.id, ondelete='CASCADE'), nullable=False) author_id = db.Column(db.Integer(), ForeignKey(User.id, ondelete='CASCADE'), nullable=False) standard_deck_id = db.Column(db.Integer(), ForeignKey(StandardDeck.id), nullable=True) active = db.Column(db.Boolean(), nullable=False)
class User(Base): __tablename__ = 'users' email_address = db.Column(db.String(256), unique=True, nullable=False, index=True) google_id = db.Column(db.String(64), unique=True, nullable=True, index=True) facebook_id = db.Column(db.String(64), unique=True, nullable=True, index=True) sms_enabled = db.Column(db.Boolean(False), index=True) phone_number = db.Column(db.String(10), unique=True, index=True)
class UserDeck(Base): __tablename__ = 'user_decks' name = db.Column(db.String(256), nullable=False) user_id = db.Column(db.Integer(), ForeignKey(User.id, ondelete='CASCADE'), nullable=False) standard_deck_id = db.Column(db.Integer(), ForeignKey(StandardDeck.id), nullable=True) active = db.Column(db.Boolean(), nullable=False) @classmethod def create_default_deck(cls, user_id: str) -> 'UserDeck': return UserDeck.create( name=default_deck_name, standard_deck_id=None, user_id=user_id, active=True, )
class Repetition(Base): __tablename__ = 'repetitions' user_id = db.Column(db.Integer(), ForeignKey(User.id, ondelete='CASCADE'), nullable=False) user_deck_id = db.Column(db.Integer(), ForeignKey(UserDeck.id, ondelete='CASCADE'), nullable=False) flashcard_id = db.Column(db.Integer(), ForeignKey(Flashcard.id, ondelete='CASCADE'), nullable=False) iteration = db.Column(db.Integer(), nullable=False) active = db.Column(db.Boolean(), nullable=False) score = db.Column(db.Integer(), nullable=True) completed_at = db.Column(db.DateTime(timezone=True), nullable=True)
class Language(Base): __tablename__ = 'languages' name = db.Column(db.String(1024), nullable=False, unique=True) locale = db.Column(db.String(64), nullable=False, unique=True)
class StandardDeck(Base): __tablename__ = 'standard_decks' name = db.Column(db.String(256), nullable=False) source = db.Column(db.String(256), nullable=True, index=True)