class Article(db.Model): " database representation of an article " __tablename__ = 'articles' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(128)) subtitle = db.Column(db.String(512)) body = db.Column(db.Text()) views = db.Column(db.Integer, default=1) category = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow) visited_users = db.Column(db.PickleType()) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) @hybrid_method def popularity(self, gravity=1.8): seconds = (self.timestamp - datetime.utcnow()).total_seconds() hours = seconds / 3600 return (self.views - 1) / (hours + 2)**gravity @popularity.expression def popularity(self, gravity=1.8): seconds = func.extract('epoch', self.timestamp - func.now()) hours = seconds / 3600 return (self.views - 1) / func.power((hours + 2), gravity) def __repr__(self): return '{}\n{}\n{}\n'.format(self.title, self.subtitle, self.body)
class User(db.Model): " a user of the application " __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(64), unique=True) username = db.Column(db.String(64), unique=True) password_hash = db.Column(db.String(128)) joined = db.Column(db.DateTime, default=datetime.utcnow) articles = db.relationship('Article', backref='author', lazy='dynamic') comments = db.relationship('Comment', backref='comment', lazy='dynamic') def __repr__(self): return "<username: {}>".format(self.username)
class Comment(db.Model, CRUDMixin): """ comments on the articles """ __tablename__ = 'comments' html = db.Column(db.Text()) timestamp = db.Column(db.DateTime, default=datetime.utcnow) disabled = db.Column(db.Boolean, default=False) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) article_id = db.Column(db.Integer, db.ForeignKey('articles.id')) def __repr__(self): return "{}\n(authored by: {} at {})".format(html, author.username, timestamp)
class User(db.Model, UserMixin, CRUDMixin): """ application users """ __tablename__ = 'users' email = db.Column(db.String(64), unique=True) username = db.Column(db.String(64), unique=True) password_hash = db.Column(db.String(128)) joined = db.Column(db.DateTime, default=datetime.utcnow) articles = db.relationship('Article', backref='author', lazy='dynamic') comments = db.relationship('Comment', backref='comment', lazy='dynamic') def has_role(self, role): return True def __repr__(self): return "<username: {}>".format(self.username)
class Article(db.Model, CRUDMixin): """ articles in the database """ __tablename__ = 'articles' title = db.Column(db.String(128)) subtitle = db.Column(db.String(512)) body = db.Column(db.Text()) views = db.Column(db.Integer, default=1) timestamp = db.Column(db.DateTime, default=datetime.utcnow) visited_users = db.Column(db.Integer) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) tags = db.relationship(Tag, lambda: article_tags, collection_class=set, backref=db.backref('articles', collection_class=set)) _tags = association_proxy('tags', 'name', creator=Tag.get_unique) @hybrid_method def popularity(self, gravity=2): seconds = (self.timestamp - datetime.utcnow()).total_seconds() hours = seconds / 3600 return (self.views - 1) / (hours + 2)**gravity @popularity.expression def popularity(self, gravity=2): seconds = func.extract('epoch', self.timestamp - func.now()) hours = seconds / 3600 return (self.views - 1) / func.power((hours + 2), gravity) def __repr__(self): return '{}\n{}\n{}\n'.format(self.title, self.subtitle, self.body)
class Tag(db.Model, CRUDMixin): """ a tag, such as 'fashion' or 'art' for each article """ __tablename__ = 'tags' name = db.Column(db.String(64), nullable=False, unique=True) def __init__(self, name=None, **kwargs): if name is not None: kwargs['name'] = name super(Tag, self).__init__(**kwargs) @classmethod def get_unique(cls, name, **kwargs): return super(Tag, cls).get_unique(name=name, **kwargs) def __repr__(self): return '{}'.format(self.name)
class Comment(db.Model): " a comment on an article " __tablename__ = 'comments' id = db.Column(db.Integer, primary_key=True) html = db.Column(db.Text()) timestamp = db.Column(db.DateTime, default=datetime.utcnow) disabled = db.Column(db.Boolean, default=False) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) article_id = db.Column(db.Integer, db.ForeignKey('articles.id')) def __repr__(self): return "{}\n(authored by: {} at {})".format(html, author.username, timestamp)
class CRUDMixin(object): """ create, read, update and delete methods for SQLAlchemy """ from sqlalchemy.exc import IntegrityError id = db.Column(db.Integer, primary_key=True) @property def columns(self): return [c.name for c in self.__table__.columns] @classmethod def get(cls, id): """ get the item in the db. """ return cls.query.get_or_404(id) @classmethod def create(cls, details): """ create a new model of this type and save it """ model = cls(**details) model.save() def read(self): """ return json of this current model """ return dict([(c, getattr(self, c)) for c in self.columns]) def update(self, **changes): """ update the model """ for attribute, c in changes.items(): setattr(self, attribute, c) self.save() def save(self): """ saves the state of the model """ try: db.session.add(self) db.session.commit() except IntegrityError as e: print('could not add to database\n{}'.format(e)) return self def delete(self): db.session.delete(self) db.session.commit()
seconds = func.extract('epoch', self.timestamp - func.now()) hours = seconds / 3600 return (self.views - 1) / func.power((hours + 2), gravity) def __repr__(self): return '{}\n{}\n{}\n'.format(self.title, self.subtitle, self.body) class Comment(db.Model, CRUDMixin): """ comments on the articles """ __tablename__ = 'comments' html = db.Column(db.Text()) timestamp = db.Column(db.DateTime, default=datetime.utcnow) disabled = db.Column(db.Boolean, default=False) author_id = db.Column(db.Integer, db.ForeignKey('users.id')) article_id = db.Column(db.Integer, db.ForeignKey('articles.id')) def __repr__(self): return "{}\n(authored by: {} at {})".format(html, author.username, timestamp) article_tags = db.Table( 'article_tags', db.Column('article_id', db.Integer, db.ForeignKey(Article.id), primary_key=True), db.Column('tag_id', db.Integer, db.ForeignKey(Tag.id), primary_key=True))