class UserRole(BaseModel): """Join table between User and Role""" user_id = foreign_key('User', primary_key=True) user = relationship('User', back_populates='user_roles') role_id = foreign_key('Role', primary_key=True) role = relationship('Role', back_populates='role_users') __repr_props__ = ('user_id', 'role_id') def __init__(self, user=None, role=None, **kwargs): super().__init__(**kwargs) if user: self.user = user if role: self.role = role
class SeriesTag(BaseModel): """Join table between Series and Tag""" series_id = foreign_key('Series', primary_key=True) series = relationship('Series', back_populates='series_tags') tag_id = foreign_key('Tag', primary_key=True) tag = relationship('Tag', back_populates='tag_series') __repr_props__ = ('series_id', 'tag_id') def __init__(self, series=None, tag=None, **kwargs): super().__init__(**kwargs) if series: self.series = series if tag: self.tag = tag
class User(Model, UserMixin): username = Column(String(50), unique=True, index=True) email = Column(String(50), unique=True, index=True) first_name = Column(String(32)) last_name = Column(String(64)) password = Column(String, nullable=True) active = Column(Boolean(name='active'), default=False) confirmed_at = Column(DateTime(), nullable=True) # Only used when SECURITY_TRACKABLE is set to True in config.py # last_login_at = Column(DateTime(), nullable=True) # current_login_at = Column(DateTime(), nullable=True) # last_login_ip = Column(String(100)) # current_login_ip = Column(String(100)) # login_count = Column(Integer) user_roles = relationship('UserRole', back_populates='user', cascade='all, delete-orphan') roles = association_proxy('user_roles', 'role', creator=lambda role: UserRole(role=role)) __repr_props__ = ('id', 'username', 'email') def __init__(self, hash_password=True, **kwargs): super().__init__(**kwargs) if 'password' in kwargs and hash_password: self.password = security_hash_password(kwargs['password'])
class ArticleTag(BaseModel): """Join table between Article and Tag""" # __tablename__ = 'article_tag' article_id = foreign_key('Article', primary_key=True) article = relationship('Article', back_populates='article_tags') tag_id = foreign_key('Tag', primary_key=True) tag = relationship('Tag', back_populates='tag_articles') __repr_props__ = ('article_id', 'tag_id') def __init__(self, article=None, tag=None, **kwargs): super().__init__(**kwargs) if article: self.article = article if tag: self.tag = tag
class Series(Model): title = Column(String(100)) slug = Column(String(100)) file_path = Column(String(255), nullable=True) header_image = Column(String(255), nullable=True) summary = Column(Text) series_articles = relationship('SeriesArticle', back_populates='series', lazy='joined', innerjoin=True, order_by='SeriesArticle.part', cascade='all, delete-orphan') articles = association_proxy( 'series_articles', 'article', creator=lambda article: SeriesArticle(article=article)) category_id = foreign_key('Category', nullable=True) category = relationship('Category', back_populates='series') series_tags = relationship('SeriesTag', back_populates='series', cascade='all, delete-orphan') tags = association_proxy('series_tags', 'tag', creator=lambda tag: SeriesTag(tag=tag)) __repr_props__ = ('id', 'title', 'articles') @on('series_articles', 'append') def on_append_series_article(self, series_article, *_): # auto increment series article part number if necessary if series_article.part is None: series_article.part = len(self.series_articles) + 1 # set the article's category to be the same as the series' category article = series_article.article article.category = self.category # set the article's tags to include the series' tags for tag in self.tags: if tag not in article.tags: article.tags.append(tag)
class Tag(Model): name = Column(String(32)) slug = Column(String(32)) tag_articles = relationship('ArticleTag', back_populates='tag') articles = association_proxy( 'tag_articles', 'article', creator=lambda article: ArticleTag(article=article)) tag_series = relationship('SeriesTag', back_populates='tag') series = association_proxy('tag_series', 'series', creator=lambda series: SeriesTag(series=series)) __repr_props__ = ('id', 'name') def __init__(self, name, **kwargs): super().__init__(**kwargs) self.name = name
class Role(Model, RoleMixin): name = Column(String(50), unique=True, index=True) description = Column(String(255), nullable=True) role_users = relationship('UserRole', back_populates='role', cascade='all, delete-orphan') users = association_proxy('role_users', 'user', creator=lambda user: UserRole(user=user)) __repr_props__ = ('id', 'name')
class SeriesArticle(Model): """Join table between Series and Article""" article = relationship('Article', back_populates='article_series', uselist=False, cascade='all, delete-orphan') part = Column(Integer) series_id = foreign_key('Series') series = relationship('Series', back_populates='series_articles') __repr_props__ = ('id', 'series_id', 'part') def __init__(self, article=None, series=None, part=None, **kwargs): super().__init__(**kwargs) if article: self.article = article if series: self.series = series if part is not None: self.part = part
class User(Model, UserMixin): username = Column(String(50), unique=True, index=True) email = Column(String(50), unique=True, index=True) first_name = Column(String(32)) last_name = Column(String(64)) password = Column(String, nullable=True) active = Column(Boolean(name='active'), default=False) confirmed_at = Column(DateTime(), nullable=True) user_roles = relationship('UserRole', back_populates='user', cascade='all, delete-orphan') roles = association_proxy('user_roles', 'role', creator=lambda role: UserRole(role=role)) articles = relationship('Article', back_populates='author') __repr_props__ = ('id', 'username', 'email') def __init__(self, hash_password=True, **kwargs): super().__init__(**kwargs) if 'password' in kwargs and hash_password: self.password = security_hash_password(kwargs['password'])
class Article(Model): title = Column(String(100)) slug = Column(String(100)) publish_date = Column(DateTime) last_updated = Column(DateTime, nullable=True) file_path = Column(String(255), nullable=True) header_image = Column(String(255), nullable=True) preview = Column(Text) html = Column(Text) category_id = foreign_key('Category', nullable=True) category = relationship('Category', back_populates='articles') __repr_props__ = ('id', 'title') @classmethod def get_published(cls): return cls.query\ .filter(cls.publish_date <= utcnow())\ .order_by(cls.publish_date.desc(), cls.last_updated.desc())\ .all()
class Article(Model): title = Column(String(100)) slug = Column(String(100)) publish_date = Column(DateTime) last_updated = Column(DateTime, nullable=True) file_path = Column(String(255), nullable=True) header_image = Column(String(255), nullable=True) preview = Column(Text) html = Column(Text) author_id = foreign_key('User') author = relationship('User', back_populates='articles') article_series_id = foreign_key('SeriesArticle', nullable=True) article_series = relationship('SeriesArticle', back_populates='article', cascade='all, delete-orphan', single_parent=True) series = association_proxy( 'article_series', 'series', creator=lambda series: SeriesArticle(series=series)) part = association_proxy('article_series', 'part') category_id = foreign_key('Category', nullable=True) category = relationship('Category', back_populates='articles') article_tags = relationship('ArticleTag', back_populates='article', cascade='all, delete-orphan') tags = association_proxy('article_tags', 'tag', creator=lambda tag: ArticleTag(tag=tag)) __repr_props__ = ('id', 'title') @classmethod def get_published(cls): return cls.query\ .filter(cls.publish_date <= utcnow())\ .order_by(cls.publish_date.desc(), cls.last_updated.desc())\ .all() def get_series_prev_next(self): if self.series: series_articles = self.series.series_articles prev = None prev_i = self.part - 2 if prev_i >= 0: prev = series_articles[prev_i] prev = {'slug': prev.article.slug, 'title': prev.article.title} next = None next_i = self.part if next_i < len(series_articles): next = series_articles[next_i] next = {'slug': next.article.slug, 'title': next.article.title} if prev and next: return prev, next elif prev: return prev, None elif next: return None, next return None, None def get_prev_next(self): if self.series: return self.get_series_prev_next() result = db.session.execute( f''' WITH articles AS ( SELECT slug, title, ROW_NUMBER() OVER (ORDER BY publish_date ASC, last_updated ASC) AS row_number FROM {Article.__tablename__} WHERE publish_date <= :now AND article_series_id IS NULL ) SELECT slug, title FROM articles WHERE row_number IN ( SELECT row_number + i FROM articles CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n WHERE slug = :slug ) ''', { 'now': utcnow(), 'slug': self.slug }) rows = [{'slug': row[0], 'title': row[1]} for row in result.fetchall()] if len(rows) == 1: return None, None elif len(rows) == 3: return rows[0], rows[2] elif rows[0]['slug'] == self.slug: return None, rows[1] elif rows[1]['slug'] == self.slug: return rows[0], None
class User(db.Model): id=db.Column(db.Integer,primary_key=True) username=db.Column(db.String(120),unique=False,nullable=False) public_id=db.Column(db.String(120),unique=True,nullable=False) email=db.Column(db.String(120),unique=True,nullable=False) password=db.Column(db.String(120),unique=False,nullable=False) comments=db.relationship("Comment",backref="creator",lazy=True) # groups=db.relationship("Group",backref="members",lazy=True) joined=db.relationship("Group",secondary=link,lazy="subquery", backref=db.backref("members",lazy=True)) @staticmethod def new_user(data): print("the data is",data) try: email=data.get("email") username=data.get("username") if isEmail(email): pass else: return "valid email is required",401 password=data.get("password") hash_pwd=password_hash(password) public_id=uuid_generator() user=User(username=username,email=email,public_id=public_id,password=hash_pwd) db.session.add(user) db.session.commit() except Exception as e: print(str(e)) return "Invalid details or user already exists",401 return "successfully created",201 def user_exists(email,pwd): print("the email calling is",email) user=User.query.filter_by(email=email).first() print("the user found calling is ",user) if user is not None: return validate_password(pwd,user.password) return False @staticmethod def join_group(current_user,name): try: group=Group.query.filter_by(group_name=name).first() user=User.query.filter_by(email=current_user.email).first() if group is None: return "no search group exists",401 user.joined.append(group) db.session.commit() except Exception as e: return str(e),401 return "successfully joined group" def get_user(email): print("call with email") user=User.query.filter_by(email=email).first() # print("details are ", {email:user.email,public_id:user.public_id}) print("the user is",user) # print("the user id ",user.public_id) try: found_user={ "username":user.username, "email":user.email, "public_id":user.public_id } except Exception as e: raise e return found_user def __repr__(self): # return {public_id:self.public_id,email:self.email} return f'{self.public_id}->{self.email}'