示例#1
0
class User(UserMixin, db.Model):

    id = db.Column(db.Integer(), primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    location = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(), default=datetime.utcnow)
    last_seen = db.Column(db.DateTime(), default=datetime.utcnow)
    name = db.Column(db.String(64), unique=True)
    username = db.Column(db.String(255))
    password = db.Column(db.String(255))
    birthday = db.Column(db.Date())
    posts = db.relationship('Post', backref='user', lazy='dynamic')
    headimg = db.Column(db.String(128), default=None)
    comments = db.relationship('Comment', backref='user', lazy='dynamic')
    messagesboard = db.relationship('Messageboard',
                                    backref='user',
                                    lazy='dynamic')
    myphotos = db.relationship('Photos', backref='user', lazy='dynamic')

    def __repr__(self):
        return "<User '{}'>".format(self.username)

    def set_password(self, password):
        self.password = bcrypt.generate_password_hash(password)

    def check_password(self, password):
        return bcrypt.check_password_hash(self.password, password)

    def ping(self):
        self.last_seen = datetime.utcnow()
        db.session.add(self)
        db.session.commit()
示例#2
0
class Course(db.Model):
    __tablename__ = 'course'

    code = db.Column(db.String(7), primary_key=True)
    title = db.Column(db.String(80), nullable=False)
    credits = db.Column(db.Integer, nullable=False)

    # many -to many with Users
    users = db.relationship('User',
                            secondary=course_list,
                            lazy='subquery',
                            backref=db.backref('courses', lazy=True))
    sessions = db.relationship('Session', back_populates='course')

    def __repr__(self):
        return f'Course<code={self.code}, title={self.title}, credits={self.credits}>'

    def save(self):
        db.session.add(self)
        db.session.commit()

    @classmethod
    def get_courses(cls):
        res = cls.query.all()
        return res

    @classmethod
    def find_by_id(cls, code):
        course = cls.query.filter(cls.code == code).first()
        return course
示例#3
0
class QuestItem(db.Model, DroppedByMixin):
    __tablename__ = "quest_item"

    _mapper_utils = {
        "files": {
            "server": ["s_QuestItem.bin"],
            "client": ["c_QuestItemRes.bin"],
            "string": ["QuestItemStr.dat"],
        },
    }

    index = db.Column(db.Integer, nullable=False)

    code = CustomColumn(db.String(32),
                        primary_key=True,
                        nullable=False,
                        mapper_key="코드")

    name = CustomColumn(db.String(256), nullable=False, mapper_key="_name")

    icon = CustomColumn(db.String(32), nullable=False, mapper_key="_icon")

    stack_size = CustomColumn(db.Integer, nullable=False, mapper_key="중복가능수")

    quest_missions = db.relationship(
        "QuestMission",
        primaryjoin="foreign(QuestMission.quest_item_code) == QuestItem.code",
    )

    quest_give_items = db.relationship(
        "QuestGiveItem",
        primaryjoin="foreign(QuestGiveItem.item_code) == QuestItem.code",
    )

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = {
            "code": self.code,
            "name": self.name,
            "icon": self.icon,
        }

        if minimal:
            return minimal_dict

        quest_objectives = self.quest_missions + self.quest_give_items

        return {
            **minimal_dict,
            "stack_size":
            self.stack_size,
            "quests": [
                quest_objective.quest.to_dict(minimal=True)
                for quest_objective in quest_objectives
            ],
            **DroppedByMixin.to_dict(self),
        }
示例#4
0
class MapPoint(db.Model):
    __tablename__ = "map_point"

    index = db.Column(db.Integer, primary_key=True, autoincrement=True)

    map_code = db.Column(db.String(32),
                         db.ForeignKey("map.code"),
                         nullable=False)
    map = db.relationship("Map", foreign_keys=[map_code])

    monster_code = db.Column(db.String(32),
                             db.ForeignKey("monster.code"),
                             nullable=False)
    monster = db.relationship("Monster", foreign_keys=[monster_code])

    x = db.Column(db.Integer, nullable=False)
    y = db.Column(db.Integer, nullable=False)
    z = db.Column(db.Integer, nullable=False)

    def to_dict(
        self,
        monster_dict: bool = False,
        map_dict: bool = False,
    ) -> dict:
        if monster_dict:
            return {
                "monster": self.monster.to_dict(minimal=True),
                "pos": {
                    "x": self.x,
                    "y": self.y,
                    "z": self.z,
                },
            }

        elif map_dict:
            return {
                "map": self.map.to_dict(minimal=True),
                "pos": {
                    "x": self.x,
                    "y": self.y,
                    "z": self.z,
                },
            }

        return {
            "map": self.map.to_dict(minimal=True),
            "monster": self.monster.to_dict(minimal=True),
            "pos": {
                "x": self.x,
                "y": self.y,
                "z": self.z,
            },
        }
示例#5
0
class Post(db.Model):
    id = db.Column(db.Integer(),primary_key=True)
    title = db.Column(db.String(255))
    text = db.Column(db.Text())
    publish_date = db.Column(db.DateTime())
    user_id = db.Column(db.Integer(),db.ForeignKey('user.id'))
    comments = db.relationship('Comment',backref = 'post',lazy = 'dynamic')
    tags=db.relationship(
        'Tag',secondary =tags,backref = db.backref('posts',lazy='dynamic')
    )
    def __init__(self,title):
        self.title = title
    
    def __repr__(self):
        return "<Post '{}'>".format(self.title)
示例#6
0
class Blog(db.Model):
    __tablename__ = 'blogs'
    __searchable__ = ['title', 'content']
    __analyzer__ = ChineseAnalyzer()

    id = db.Column(db.Integer, primary_key=True)
    time = db.Column(db.BigInteger)
    author = db.Column(db.String(255))
    title = db.Column(db.String(255), unique=True)
    content = db.Column(LONGTEXT)

    comments = db.relationship('Comment', backref='blogs', lazy='dynamic')
    tags = db.relationship('Tag', secondary=tags, backref=db.backref('blogs', lazy='dynamic'))

    def __init__(self, author, title, content):
        self.author = author
        self.title = title
        self.content = content

    def __repr__(self):
        return "<Blog '{}'>".format(self.title)

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    def to_dict(self):
        """Transforms a model into a dictionary which can be dumped to JSON."""
        # first we get the names of all the columns on your model
        columns = [c.key for c in class_mapper(self.__class__).columns]
        # then we return their values in a dict
        return dict((c, getattr(self, c)) for c in columns)

    # 返回除了 content, comments 之外的值
    @staticmethod
    def query_title():
        sql_str = '''
        SELECT blogs.id, blogs.time, blogs.author, blogs.title, group_concat(tags.title) tag
        FROM blogs LEFT JOIN blog_tags ON blogs.id=blog_tags.blog_id
        left join tags ON tags.id=blog_tags.tag_id
        group by blogs.id;
        '''
        ret = db.engine.execute(sql_str).fetchall()
        return [dict(r) for r in ret]
示例#7
0
class PetSkillStone(
        db.Model,
        BaseMixin,
        DroppedByMixin,
        RandomBoxMixin,
):
    __tablename__ = "pet_skill_stone"

    _mapper_utils = {
        "files": {
            "server": ["s_PetSkillStoneItem.bin"],
            "client": ["c_PetSkillStoneItemRes.bin"],
            "string": ["PetSkillStoneItemStr.dat"],
        }
    }

    skill_code = CustomColumn(db.String(32),
                              db.ForeignKey("pet_skill.code"),
                              nullable=False,
                              mapper_key="대상코드")

    skill_data = db.relationship("PetSkill", foreign_keys=[skill_code])

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = BaseMixin.to_dict(self, minimal)

        if minimal:
            return minimal_dict

        return {
            **minimal_dict,
            "skill": self.skill_data.to_dict(),
            **DroppedByMixin.to_dict(self),
            **RandomBoxMixin.to_dict(self),
        }
示例#8
0
class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), nullable=False)
    author = db.Column(db.String(80))
    full_text = db.Column(TEXT, nullable=False)
    link = db.Column(db.String(250), nullable=False)

    sessions = db.relationship('Session',
                               secondary=session_articles,
                               lazy='subquery',
                               backref=db.backref('articles', lazy=True))

    # many to many

    def __repr__(self):
        return f'Article<id={self.id}, title={self.title}, author={self.author}>'

    def save(self):
        db.session.add(self)
        db.session.commit()

    @classmethod
    def find_by_id(cls, article_id):
        return cls.query.filter(cls.id == article_id).first()

    @classmethod
    def get_articles(cls):
        return cls.query.all()
示例#9
0
class ProductBook(db.Model, BaseMixin, SoldByMixin):
    __tablename__ = "product_book"

    _mapper_utils = {
        "files": {
            "server": ["s_ProductBook.bin"],
            "client": ["c_ProductRes.bin"],
            "string": ["ProductStr.dat"],
        },
    }

    production_code = CustomColumn(db.String(32),
                                   db.ForeignKey("production.code"),
                                   nullable=False,
                                   mapper_key="대상코드")

    production = db.relationship("Production",
                                 foreign_keys=[production_code],
                                 uselist=False)

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = BaseMixin.to_dict(self, minimal)

        if minimal:
            return minimal_dict

        return {
            **minimal_dict,
            "production": self.production.to_dict(minimal=True),
            **SoldByMixin.to_dict(self),
        }
示例#10
0
class Map(db.Model):
    __tablename__ = "map"

    _mapper_utils = {
        "files": {
            "string": ["AreaStr.dat"],
        },
    }

    code = db.Column(db.String(32), primary_key=True, nullable=False)

    name = db.Column(db.String(128), nullable=False)

    left = CustomColumn(db.Float)
    top = CustomColumn(db.Float)
    width = CustomColumn(db.Float)
    height = CustomColumn(db.Float)

    map_points = db.relationship(
        "MapPoint", primaryjoin="foreign(MapPoint.map_code) == Map.code")

    def _parse_row(row: dict) -> "Map":
        code = row["Code"]
        lwth = MAP_CODE_TO_LTWH.get(code, None)

        if lwth is None:
            # Not a "real" map but rather island or an area
            # which only have a name and code
            return {"code": code, "name": row[LANGUAGE]}

        l, t, w, h = [float(num) for num in lwth.split(",")]

        return {
            "code": code,
            "name": row[LANGUAGE],
            "left": l,
            "top": t,
            "width": w,
            "height": h,
        }

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = {
            "code": self.code,
            "name": self.name,
            "left": self.left,
            "top": self.top,
            "width": self.width,
            "height": self.height,
        }

        if minimal:
            return minimal_dict

        return {
            **minimal_dict, "points":
            [point.to_dict(monster_dict=True) for point in self.map_points]
        }
示例#11
0
class Post(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    title = db.Column(db.String(255))
    subtitle = db.Column(db.String(255))
    text = db.Column(db.Text())
    publish_date = db.Column(db.DateTime())
    private = db.Column(db.Boolean())
    user_id = db.Column(db.Integer(), db.ForeignKey('user.id'))
    comments = db.relationship('Comment', backref='post', lazy='dynamic')
    body_html = db.Column(db.Text())
    tags = db.relationship('Tag',
                           secondary=tags,
                           backref=db.backref('posts', lazy='dynamic'))
    '''
    @staticmethod
    def on_changed_body(target,value,oldvalue,intitiator):
        allowed_tag = ['a','abbr','acronym','b','blockquote','code','div','em','i','li','ol','pre','strong','table','thead','tbody','tr','th','ul','h1','h2','h3','h4','h5','h6','p',]
        target.body_html = bleach.linkify(bleach.clean(markdown(value,output_html = 'html'),tags=allowed_tag,strip=True))
    '''

    #处理body字段变化的函数
    @staticmethod
    def on_changed_post(target, value, oldvalue, initiaor):
        allow_tags = [
            'a', 'abbr', 'acronym', 'b', 'blockquote', 'code', 'em', 'i', 'li',
            'ol', 'pre', 'strong', 'ul', 'h1', 'h2', 'h3', 'p', 'img'
        ]
        #转换markdown为html,并清洗html标签

        target.body_html = bleach.linkify(
            bleach.clean(
                markdown(value,
                         output_form='html',
                         extensions=['extra', 'codehilite']),
                tags=allow_tags,
                strip=True,
                attributes={
                    '*': ['class'],
                    'a': ['href', 'rel'],
                    'img': ['src', 'alt'],  #支持<img src …>标签和属性
                }))

    def __repr__(self):
        return "<Post '{}'>".format(self.title)
示例#12
0
文件: session.py 项目: teaQL/onTrack
class Session(db.Model):
    __tablename__ = 'session'

    id = db.Column(db.Integer, primary_key=True)
    start_time = db.Column(db.DateTime,
                           server_default=func.now(),
                           nullable=False)
    duration_s = db.Column(db.Integer, nullable=False)

    #? 1 course - Many sessions
    course_code = db.Column(db.String(7), db.ForeignKey('course.code'))
    course = db.relationship('Course', back_populates='sessions')
    #? 1 user - Many study blocks
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    user = db.relationship('User', back_populates='sessions')

    db.UniqueConstraint(start_time, user_id)

    def __repr__(self):
        return f"Session<id={self.id}, start={self.start_time}, duration={self.duration_s}, course_code={self.course_code}, user={self.user_id}>"

    def save(self):
        db.session.add(self)
        db.session.commit()

    def add_article(self, article):
        self.articles.append(article)
        self.save()

    def remove_article(self, article_id):
        article = Article.find_by_id(article_id)
        self.articles.remove(article)
        self.save()

    @classmethod
    def find_by_id(cls, session_id):
        return cls.query.filter(cls.id == session_id).first()

    @classmethod
    def find_course_sessions(cls, user_id, course_code):
        return cls.query.filter(cls.user_id == user_id).filter(
            cls.course_code == course_code).all()
示例#13
0
class QuestMission(db.Model):
    __tablename__ = "quest_mission"

    index = db.Column(db.Integer, primary_key=True, autoincrement=True)
    work_type = db.Column(db.Enum(QuestWorkType), nullable=False)
    work_value = db.Column(db.String(32))

    quest_code = db.Column(db.String(32),
                           db.ForeignKey("quest.code"),
                           nullable=False)

    quest = db.relationship("Quest", foreign_keys=[quest_code])

    map_code = db.Column(db.String(32), db.ForeignKey("map.code"))
    map = db.relationship("Map", foreign_keys=[map_code], uselist=False)

    x = db.Column(db.Float)
    y = db.Column(db.Float)

    count = db.Column(db.Integer, nullable=False)

    npc_code = db.Column(db.String(32), db.ForeignKey("npc.code"))
    npc = db.relationship("Npc", foreign_keys=[npc_code], uselist=False)

    item_code = db.Column(db.String(32), db.ForeignKey("item_list.code"))
    item = db.relationship("ItemList", foreign_keys=[item_code], uselist=False)

    monster_code = db.Column(db.String(32), db.ForeignKey("monster.code"))
    monster = db.relationship("Monster",
                              foreign_keys=[monster_code],
                              uselist=False)

    quest_item_code = db.Column(db.String(32),
                                db.ForeignKey("quest_item.code"))
    quest_item = db.relationship("QuestItem",
                                 foreign_keys=[quest_item_code],
                                 uselist=False)

    def to_dict(self) -> dict:
        return {
            "work_type":
            self.work_type.to_dict(),
            "work_value":
            self.work_value,
            "map": (self.map.to_dict(minimal=True) if self.map else None),
            "pos": {
                "x": self.x,
                "y": self.y,
            },
            "count":
            self.count,
            "npc":
            self.npc.to_dict(minimal=True) if self.npc else None,
            "item":
            self.item.to_dict() if self.item else None,
            "monster":
            (self.monster.to_dict(minimal=True) if self.monster else None),
            "quest_item": (self.quest_item.to_dict(
                minimal=True) if self.quest_item else None)
        }
示例#14
0
class QuestSelectableItem(db.Model):
    __tablename__ = "quest_selectable_item"

    index = db.Column(db.Integer, primary_key=True, autoincrement=True)

    quest_code = db.Column(db.String(32),
                           db.ForeignKey("quest.code"),
                           nullable=False)
    quest = db.relationship("Quest", foreign_keys=[quest_code])

    item_code = db.Column(db.String(32),
                          db.ForeignKey("item_list.code"),
                          nullable=False)
    item = db.relationship("ItemList", foreign_keys=[item_code], uselist=False)

    amount = db.Column(db.Integer, nullable=False)

    def to_dict(self) -> dict:
        return {
            "item": self.item.to_dict(),
            "amount": self.amount,
        }
示例#15
0
class Drop(db.Model):
    __tablename__ = "drop"

    index = db.Column(db.Integer, primary_key=True, autoincrement=True)
    quantity = db.Column(db.Integer, nullable=False, default=1)

    monster_code = db.Column(db.String(32),
                             db.ForeignKey("monster.code"),
                             nullable=False)

    monster = db.relationship("Monster",
                              foreign_keys=[monster_code])

    item_code = db.Column(db.String(32),
                          db.ForeignKey("item_list.code"),
                          nullable=False)

    item = db.relationship("ItemList",
                           foreign_keys=[item_code])

    def to_dict(
        self,
        item_dict: bool = False,
        monster_dict: bool = False
    ) -> dict:
        if item_dict:
            return {
                "item": self.item.to_dict(with_item_data=True),
                "quantity": self.quantity,
            }

        elif monster_dict:
            return {
                "monster": self.monster.to_dict(minimal=True),
                "quantity": self.quantity,
            }
示例#16
0
class User(UserMixin,db.Model):
    
    id =db.Column(db.Integer(),primary_key = True)
    email = db.Column(db.String(64),unique = True,index = True)
    username = db.Column(db.String(255))
    password = db.Column(db.String(255))
    posts = db.relationship('Post',backref = 'user',lazy = 'dynamic')

    
    
    def __repr__(self):
        return "<User '{}'>".format(self.username)




    def set_password (self,password):
        self.password = bcrypt.generate_password_hash(password)
    
    def check_password(self,password):
        return bcrypt.check_password_hash(self.password,password)
示例#17
0
class ArticleRatings(db.Model):
    __tablename__ = 'article_ratings'

    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
    user = db.relationship('User', back_populates='article_ratings')

    article_id = db.Column(db.Integer,
                           db.ForeignKey('article.id'),
                           primary_key=True)
    rating = db.Column(db.Integer, nullable=False)

    def __repr__(self):
        return f'Rating<user_id: {self.user_id}, article_id: {self.article_id}, rating: {self.rating}>'

    def remove(self):
        db.session.delete(self)
        db.session.commit()

    @classmethod
    def find_by_id(cls, user_id, article_id):
        return cls.query.filter(cls.user_id == user_id).filter(
            cls.article_id == article_id).first()
示例#18
0
class SkillBook(
    db.Model, BaseMixin,
    SoldByMixin
):
    __tablename__ = "skill_book"

    _mapper_utils = {
        "files": {
            "server": [
                "s_SkillBookItem.bin"
            ],
            "client": [
                "c_SkillBookItemRes.bin"
            ],
            "string": [
                "SkillBookItemStr.dat"
            ],
        },
    }

    skill_code = CustomColumn(
        db.String(32), db.ForeignKey("player_skill.code"),
        nullable=False, mapper_key="대상코드")

    skill = db.relationship("PlayerSkill", foreign_keys=[skill_code],
                            uselist=False)

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = BaseMixin.to_dict(self, minimal)

        if minimal:
            return minimal_dict

        return {
            **minimal_dict,
            "skill": self.skill.to_dict() if self.skill else None,
            **SoldByMixin.to_dict(self),
        }
示例#19
0
class QuestScroll(
        db.Model,
        BaseMixin,
        DroppedByMixin,
        SoldByMixin,
):
    __tablename__ = "quest_scroll"

    _mapper_utils = {
        "files": {
            "server": ["s_QuestScrollItem.bin"],
            "client": ["c_QuestScrollItemRes.bin"],
            "string": ["QuestScrollItemStr.dat"],
        },
    }

    quest_code = CustomColumn(db.String(32),
                              db.ForeignKey("quest.code"),
                              nullable=False,
                              mapper_key="대상코드")

    quest = db.relationship("Quest", foreign_keys=[quest_code], uselist=False)

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = BaseMixin.to_dict(self, minimal)

        if minimal:
            return minimal_dict

        return {
            **minimal_dict,
            "quest":
            self.quest.to_dict(minimal=True) if self.quest else None,
            **SoldByMixin.to_dict(self),
            **DroppedByMixin.to_dict(self),
        }
示例#20
0
文件: user.py 项目: teaQL/onTrack
class User(db.Model):
    __tablename__ = 'user'
    # Define attributes
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(150), nullable=False)
    firstname = db.Column(db.String(150), nullable=False)
    lastname = db.Column(db.String(150), nullable=False)
    password = db.Column(db.String(30), nullable=False)
    bio = db.Column(db.String(250), server_default='')
    # TODO: Add a table for year in school
    # year_in_school

    # course_of_study = db.Column(db.Integer, db.ForeignKey('course_of_study.id'))
    # course_of_study_id = db.Column(db.Integer, db.ForeignKey('Course_Of_Study.id'))
    # course_of_study = db.relationship('Course_Of_Study', back_populates='user')

    sessions = db.relationship('Session',
                               back_populates='user',
                               order_by='Session.start_time.desc()')

    article_ratings = db.relationship('ArticleRatings', back_populates='user')

    def __repr__(self):
        return f"User<id={self.id}, email={self.email}, firstname={self.firstname}, lastname={self.lastname}>"

    def save(self):
        # Save a user to a db
        db.session.add(self)
        db.session.commit()
        db.session.refresh(self)

    def verify_password(self, other_password):
        # TODO: Hash the passwords
        return self.password == other_password

    def get_courses(self):
        return self.courses

    def add_course(self, code):
        course = Course.find_by_id(code)
        self.courses.append(course)
        self.save()

    def remove_course(self, code):
        course = Course.find_by_id(code)
        self.courses.remove(course)
        self.save()

    def get_sessions(self, course_code=None):
        if not course_code:
            return self.sessions
        return Session.find_course_sessions(self.id, course_code)

    def get_articles(self):
        return self.article_ratings

    def add_rating(self, article_id, rating):
        article_rating = ArticleRatings(user_id=self.id,
                                        article_id=article_id,
                                        rating=rating)
        self.article_ratings.append(article_rating)
        self.save()

    def remove_rating(self, article_id):
        article_rating = ArticleRatings.find_by_id(self.id, article_id)
        print(article_rating)
        article_rating.remove()
        # self.article_ratings.remove(article_rating)
        # self.save()

    @classmethod
    def find_by_email(cls, email):
        if not email:
            return None
        res = User.query.filter(cls.email == email).first()
        return res

    @classmethod
    def find_by_id(cls, id):
        if not id:
            return None
        try:
            res = User.query.filter(cls.id == id).first()
        except:
            return None
        return res

    @classmethod
    def get_users(cls, limit=15):
        res = cls.query.limit(limit).all()
        return res

    @classmethod
    def remove_by_id(cls, user_id):
        cls.query.filter(cls.id == user_id).delete()
        db.session.commit()
示例#21
0
class JournalEntry(db.Model):
    """Model for journal entries."""
    id = db.Column(db.Integer, primary_key=True)
    create_date = db.Column(db.Date, default=func.now(), index=True)
    updated_at = db.Column(db.DateTime,
                           default=func.now(),
                           onupdate=func.now(),
                           nullable=False,
                           server_default=func.now())
    contents = db.Column(db.String)
    owner_id = db.Column(db.Integer,
                         db.ForeignKey(User.id, ondelete="cascade"),
                         index=True)
    owner = db.relationship(
        User,
        backref=backref('entries', cascade="all,delete"),
    )
    __table_args__ = (db.UniqueConstraint('owner_id',
                                          'create_date',
                                          name='_id_date'), )

    def __str__(self):
        return repr(self.id)

    def __repr__(self):
        return f'< JournaEntry id={self.id} create_date={self.create_date}'

    @property
    def html(self) -> str:
        """Return HTML rendering of markdown contents."""
        return markdown.markdown(self.contents)

    @property
    def date_string(self) -> str:
        """Date as YYYY-MM-DD."""
        return self.create_date.strftime('%Y-%m-%d')

    @property
    def date_human(self) -> str:
        """A pretty and human readable date."""
        return self.create_date.strftime('%B %d, %Y, a %A')

    @property
    def next(self):
        found = JournalEntry.query.filter(
            JournalEntry.owner_id == self.owner_id).order_by(
                JournalEntry.create_date).filter(
                    JournalEntry.create_date > self.create_date).first()
        if found:
            if found.id != self.id:
                return found
        return None

    @property
    def previous(self):

        found = JournalEntry.query.filter(
            JournalEntry.owner_id == self.owner_id).filter(
                JournalEntry.create_date < self.create_date).order_by(
                    JournalEntry.create_date.desc()).first()

        if found:
            if found.id != self.id:
                return found
        return None
示例#22
0
class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, index=True)
    password = db.Column(db.String(200))
    email = db.Column(db.String(200), unique=True, index=True)
    registered_on = db.Column(db.DateTime, default=datetime.datetime.utcnow)
    first_name = db.Column(db.String(200))
    last_name = db.Column(db.String(200))
    active = db.Column(db.Boolean())
    confirmed_at = db.Column(db.DateTime())
    roles = db.relationship('Role',
                            secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

    # ========== flask-login methods ==========
    @property
    def is_authenticated(self):
        return True

    @property
    def is_active(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        return self.id

    def get_latest_entry(self, ) -> "JournalEntry":
        """Return the chronologically latest JournalEntry."""
        sess = db.session.object_session(self)
        if sess is None:
            try:
                db.session.add(self)
            except sqlalchemy.exc.InvalidRequestError:
                pass
        return db.session.query(JournalEntry).filter(
            JournalEntry.owner_id == self.id).order_by(
                JournalEntry.create_date.desc()).first()

    def query_all_entries(self):
        return JournalEntry.query.filter(JournalEntry.owner_id == self.id)

    def get_all_years(self, ) -> 'iterable[datetime.datetime]':
        """Return a list of dates corresponding to the range of
        years encompassed by all journal entries."""
        # define earliest and latest years of entries
        start_year = self.query_all_entries().order_by(
            JournalEntry.create_date).first()
        end_year = self.query_all_entries().order_by(
            JournalEntry.create_date.desc()).first()
        if start_year and end_year:
            for y in range(start_year.create_date.year,
                           end_year.create_date.year + 1):
                # find any entry within this year but before next year
                found = self.query_all_entries().filter(
                    JournalEntry.create_date >= datetime.datetime(
                        y, 1, 1, 0, 0)).filter(
                            JournalEntry.create_date < datetime.datetime(
                                y + 1, 1, 1, 0, 0)).first()
                # only yield this year if has an entry
                if found:
                    yield datetime.datetime(y, 1, 1, 0, 0)

    def next_entry(self, e: "JournalEntry") -> "JournalEntry":
        """Return the first JournalEntry that falls chronologically after
        the given entry."""
        return self.query_all_entries().filter(
            JournalEntry.create_date > e.create_date).first()

    def previous_entry(self, e: "JournalEntry") -> "JournalEntry":
        """Return the first JournalEntry that falls chronologically before
        the given entry."""
        return self.query_all_entries().filter(
            JournalEntry.create_date < e.create_date).order_by(
                JournalEntry.create_date.desc()).first()
示例#23
0
文件: npc.py 项目: eiwSrvt/flandria
class Npc(db.Model):
    __tablename__ = "npc"

    _mapper_utils = {
        "files": {
            "server": [
                "s_MerchantChar.bin",
                "s_GuardChar.bin",
                "s_CitizenChar.bin"
            ],
            "client": [
                "c_MerchantCharRes.bin",
                "c_GuardCharRes.bin",
                "c_CitizenCharRes.bin"
            ],
            "string": [
                "MerchantCharStr.dat",
                "GuardCharStr.dat",
                "CitizenCharStr.dat"
            ],
        },
        "options": {
            "image_key": "모델명"
        }
    }

    index = db.Column(db.Integer, nullable=False)

    code = CustomColumn(db.String(32), primary_key=True, nullable=False,
                        mapper_key="코드")

    name = CustomColumn(db.String(128), nullable=False,
                        mapper_key="_name")

    icon = CustomColumn(db.String(128), nullable=False,
                        mapper_key="_icon")

    level = CustomColumn(db.Integer, nullable=False,
                         mapper_key="기준레벨")

    shop_items = db.relationship(
        "NpcShopItem",
        primaryjoin="foreign(NpcShopItem.npc_code) == Npc.code"
    )

    quests = db.relationship(
        "Quest",
        primaryjoin="foreign(Quest.start_npc_code) == Npc.code"
    )

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = {
            "code": self.code,
            "name": self.name,
            "icon": self.icon,
            "level": self.level,
        }

        if minimal:
            return minimal_dict

        return {
            **minimal_dict,
            "shop_items": [shop_item.to_dict(item_dict=True)
                           for shop_item in self.shop_items
                           # Some NPCs sell items that do no longer exist
                           # or are not included in the database (like
                           # commerce goods), so those will be filtered
                           # out for now to prevent errors.
                           if shop_item.item],
            "quests": [quest.to_dict(minimal=True) for quest in self.quests],
        }
示例#24
0
class Monster(db.Model):
    __tablename__ = "monster"

    _mapper_utils = {
        "files": {
            "server": ["s_MonsterChar.bin"],
            "client": ["c_MonsterCharRes.bin"],
            "string": ["MonsterCharStr.dat"],
        },
        "options": {
            "image_key": "모델명"
        },
    }

    index = db.Column(db.Integer, nullable=False)

    code = CustomColumn(db.String(32), primary_key=True, mapper_key="코드")

    name = CustomColumn(db.String(256), nullable=False, mapper_key="_name")

    icon = CustomColumn(db.String(32), nullable=False, mapper_key="_icon")

    rating_type = CustomColumn(db.Enum(RatingType),
                               nullable=False,
                               mapper_key="몬스터등급타입",
                               transform=lambda val: RatingType(val))

    level = CustomColumn(db.Integer, nullable=False, mapper_key="기준레벨")

    hp = CustomColumn(db.Integer, nullable=False, mapper_key="기준최대HP")

    range = CustomColumn(db.Enum(MonsterRange),
                         nullable=False,
                         mapper_key="공격거리타입",
                         transform=lambda val: MonsterRange(val))

    area = CustomColumn(db.Enum(Area),
                        nullable=False,
                        mapper_key="필드구분",
                        transform=lambda val: Area(val))

    experience = CustomColumn(db.Integer, nullable=False, mapper_key="보상경험치")

    minimal_damage = CustomColumn(db.Integer,
                                  nullable=False,
                                  mapper_key="최소물공력")

    maximal_damage = CustomColumn(db.Integer,
                                  nullable=False,
                                  mapper_key="최대물공력")

    physical_defense = CustomColumn(db.Integer,
                                    nullable=False,
                                    mapper_key="물방력")

    magic_defense = CustomColumn(db.Integer, nullable=False, mapper_key="마항력")

    attack_range = CustomColumn(db.Float,
                                nullable=False,
                                mapper_key="기본사정거리",
                                transform=florensia_meter_transform)

    tameable = CustomColumn(db.Boolean, mapper_key="테이밍", nullable=False)

    drops = db.relationship(
        "Drop", primaryjoin="foreign(Drop.monster_code) == Monster.code")

    map_points = db.relationship(
        "MapPoint",
        primaryjoin="foreign(MapPoint.monster_code) == Monster.code")

    quest_missions = db.relationship(
        "QuestMission",
        primaryjoin="foreign(QuestMission.monster_code) == Monster.code")

    vision_range = CustomColumn(db.Float,
                                nullable=False,
                                mapper_key="선공시야",
                                transform=florensia_meter_transform)

    # If you perform an action close to the range
    # attack vision range of the monster, you will
    # also get aggro
    attack_vision_range = CustomColumn(db.Float,
                                       nullable=False,
                                       mapper_key="요청시야",
                                       transform=florensia_meter_transform)

    messages_code = CustomColumn(db.String(32),
                                 mapper_key="오브젝트채팅",
                                 transform=lambda v: v if v != "#" else None)

    monster_message = db.relationship("MonsterMessage", uselist=False)

    # Skill 1
    skill_1_code = CustomColumn(db.String(32),
                                db.ForeignKey("monster_skill.code"),
                                mapper_key="부가Action1코드",
                                transform=lambda v: v if v != "#" else None)

    skill_1_chance = CustomColumn(db.Float,
                                  mapper_key="부가Action1선택율",
                                  transform=florensia_probability_transform)

    skill_1 = db.relationship("MonsterSkill", foreign_keys=[skill_1_code])

    # Skill 2
    skill_2_code = CustomColumn(db.String(32),
                                db.ForeignKey("monster_skill.code"),
                                mapper_key="부가Action2코드",
                                transform=lambda v: v if v != "#" else None)

    skill_2_chance = CustomColumn(db.Float,
                                  mapper_key="부가Action2선택율",
                                  transform=florensia_probability_transform)

    skill_2 = db.relationship("MonsterSkill", foreign_keys=[skill_2_code])

    def to_dict(self, minimal: bool = False) -> dict:
        minimal_dict = {
            "code": self.code,
            "name": self.name,
            "icon": self.icon,
            "rating": self.rating_type.to_dict(),
            "level": self.level,
            "area": self.area.to_dict(),
        }

        if minimal:
            return minimal_dict

        # Get monster skills as a list
        skills = []
        for i in range(1, 3):
            skill = getattr(self, f"skill_{i}")
            if skill:
                skill_dict = skill.to_dict()
                skill_dict["chance"] = getattr(self, f"skill_{i}_chance")
                skills.append(skill_dict)

        return {
            **minimal_dict, "hp":
            self.hp,
            "range":
            self.range.to_dict(),
            "experience":
            self.experience,
            "minimal_damage":
            self.minimal_damage,
            "maximal_damage":
            self.maximal_damage,
            "physical_defense":
            self.physical_defense,
            "magic_defense":
            self.magic_defense,
            "attack_range":
            self.attack_range,
            "tamable":
            self.tameable,
            "vision_range":
            self.vision_range,
            "attack_vision_range":
            self.attack_vision_range,
            "messages":
            (self.monster_message.to_dict() if self.monster_message else None),
            "skills":
            skills,
            "map_points":
            [point.to_dict(map_dict=True) for point in self.map_points],
            "drops": [drop.to_dict(item_dict=True) for drop in self.drops],
            "quests": [
                mission.quest.to_dict(minimal=True)
                for mission in self.quest_missions
            ]
        }
示例#25
0
    # Link seal option to table. Used to reference the table later.
    # This is done in the update_database.py loop.
    seal_option_type = CustomColumn(db.Enum(SealOptionType),
                                    nullable=False,
                                    mapper_key="_seal_option_type")


# Add columns with data dynamically
for i in range(0, 63):
    # Option code
    setattr(
        SealOption, f"option_{i}_code",
        CustomColumn(db.String(32),
                     db.ForeignKey("seal_option_data.code"),
                     mapper_key=f"옵션코드{i}"))

    # Option probability
    setattr(
        SealOption, f"option_{i}_chance",
        CustomColumn(db.Float,
                     mapper_key=f"확률{i}",
                     transform=(lambda v: florensia_probability_transform(v)
                                if v != 0 else None)))

    # Option relationship
    setattr(
        SealOption, f"option_{i}",
        db.relationship("SealOptionData",
                        foreign_keys=[getattr(SealOption,
                                              f"option_{i}_code")]))
示例#26
0
class User(db.Model, UserMixin):
    id = db.Column(db.Integer(), primary_key=True)
    username = db.Column(db.String(20), unique=True)
    bio = db.Column(db.String(100))
    gender = db.Column(db.SmallInteger(), default=0)  # 1 男 2 女 0 未填写
    email = db.Column(db.String(50), unique=True, index=True)
    password = db.Column(db.String(255))
    reg_date = db.Column(db.TIMESTAMP(), server_default=func.now())
    last_login_date = db.Column(db.DateTime())
    wb_uid = db.Column(db.String(20))
    avatar = db.Column(db.String(500))
    tasks = db.relationship('Task', backref='user', lazy='dynamic')

    comments = db.relationship('Comment', backref='user', lazy='dynamic')

    following = db.relationship('User',
                                secondary=follows,
                                primaryjoin=(follows.c.user_id == id),
                                secondaryjoin=(follows.c.follow_id == id),
                                backref=db.backref('follower', lazy='dynamic'),
                                lazy='dynamic')

    liked = db.relationship('Likes', backref='user', lazy='dynamic')

    def __init__(self, username):
        self.username = username

    def __repr__(self):
        return '<User: {}>'.format(self.username)

    # 检查是否关注
    def check_following(self, user_id):
        if User.query.get(user_id) in self.following.all():
            return True

    # 互相关注的好友
    def friends(self):
        return list(set(self.following.all()) & set(self.follower.all()))

    # 添加关注
    def add_following(self, user_id):
        self.following.append(User.query.get(user_id))
        db.session.add(self)
        db.session.commit()

    # 取消关注
    def cancel_following(self, user_id):
        self.following.remove(User.query.get(user_id))
        db.session.add(self)
        db.session.commit()

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password, password)

    def count_task(self):
        return '创建了{}个任务,完成了{}个'.format(
            len(self.tasks.all()), len(self.tasks.filter_by(status=1).all()))

    def unfinish_task(self):
        return len(self.tasks.all()) - len(
            self.tasks.filter_by(status=1).all())

    # 从微博注册用户
    def wb_reg(self, wb_uid):
        if not User.query.filter_by(wb_uid=wb_uid).first():
            self.wb_uid = wb_uid

    # 查询当前登录用户关注的人中是否有人关注了页面显示的用户
    def relation(self):
        if current_user.username != self.username:
            return list(
                set(current_user.following.all()) & set(self.follower.all()))

    def gender_text(self):
        return '他' if self.gender else '她'

    # 取用户头像,为空则取默认头像
    def get_avatar(self):
        if self.avatar:
            return '/static/images/' + self.avatar
        else:
            if self.gender == 0:
                return '/static/images/0.png'
            else:
                return '/static/images/1.png'

    # 圈子内容
    def circle_task(self):
        query_1 = and_(
            Task.user_id.in_([user.id for user in self.following.all()]),
            Task.public_level == '3') if self.following.all() else None  # 关注的
        query_2 = and_(Task.user_id.in_([
            user.id for user in self.friends()
        ]), Task.public_level == '2') if self.friends() else None  # 互相关注的
        return Task.query.filter(or_(Task.user_id == self.id, query_1,
                                     query_2)).order_by(
                                         Task.create_time.desc()).all()
示例#27
0
class Task(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(),
                        db.ForeignKey('user.id'),
                        nullable=False,
                        index=True)
    title = db.Column(db.String(100))
    text = db.Column(db.Text())
    create_time = db.Column(db.TIMESTAMP(), server_default=func.now())
    update_time = db.Column(db.DateTime(), onupdate=func.now())
    done_time = db.Column(db.DateTime())
    deadline = db.Column(db.DateTime(), nullable=False)
    status = db.Column(db.SmallInteger(), default=0)  # 0:进行中 1:已完成 2:暂停 9:删除
    public_level = db.Column(db.SmallInteger(), default=3,
                             index=True)  # 1:仅自己可见   2:我关注的人可见   3:所有人可见
    overtime = db.Column(db.Boolean, default=0)  # 任务结束后: 0:未超时 1:超时
    comment_allowed = db.Column(db.Boolean,
                                default=1)  # 0:禁止评论并隐藏所有评论内容 1:允许评论
    comments = db.relationship('Comment', backref='task', lazy='dynamic')

    liked = db.relationship('Likes', backref='task', lazy='dynamic')

    def __init__(self, title):
        self.title = title

    def __repr__(self):
        return '<Task: {}|User:{}>'.format(self.title, self.user_id)

    # 判断任务是否超时
    def is_overtime(self):
        if self.status == 0 and self.deadline > datetime.now():
            return False
        elif self.status == 1 and self.overtime == 0:
            return False
        else:
            return True

    # 超时时间
    def over_time(self):
        if self.status == 0 and self.deadline < datetime.now():
            over_time = datetime.now() - self.deadline
            if over_time.total_seconds() < 3600:
                return ''.join(
                    ['已超时',
                     str(int(over_time.total_seconds() / 60)), '分钟'])
            elif 3600 <= over_time.total_seconds() < 86400:
                return ''.join(
                    ['已超时',
                     str(int(over_time.total_seconds() / 3600)), '小时'])
            else:
                return ''.join(
                    ['已超时',
                     str(int(over_time.total_seconds() / 86400)), '天'])
        elif self.status == 1:
            over_time = self.done_time - self.deadline
            if over_time.total_seconds() < 3600:
                return ''.join(
                    ['超时',
                     str(int(over_time.total_seconds() / 60)), '分钟完成'])
            elif 3600 <= over_time.total_seconds() < 86400:
                return ''.join(
                    ['超时',
                     str(int(over_time.total_seconds() / 3600)), '小时完成'])
            else:
                return ''.join(
                    ['超时',
                     str(int(over_time.total_seconds() / 86400)), '天完成'])
        else:
            pass

    # 给任务点赞的所有user_id
    def liked_user(self):
        return list(u.user_id for u in self.liked.all())

    # 判断是否已点赞
    def check_liked(self):
        if current_user.id in self.liked_user():
            return True

    # 距离超时一小时
    def one_hour_deadline(self):
        the_time = self.deadline - datetime.now()
        if 0 < the_time.total_seconds() < 3600:
            return True

    # 判断当前用户是否有权限查看当前task
    def task_auth(self):
        task_user = User.query.get(self.user_id)
        if current_user.id == self.user_id or self.public_level == 3 or (
                current_user in task_user.follower.all()
                and self.public_level == 2):
            return True
        else:
            return False
示例#28
0
class ItemSet(db.Model):
    __tablename__ = "item_set"

    _mapper_utils = {
        "files": {
            "server": ["s_SetItemData.bin"],
            "string": ["SetNameStr.dat"],
        },
    }

    code = CustomColumn(db.String(32),
                        primary_key=True,
                        nullable=False,
                        mapper_key="코드")

    name = CustomColumn(db.String(256), nullable=False, mapper_key="_name")

    weapon_code = CustomColumn(db.String(32),
                               db.ForeignKey("item_list.code"),
                               mapper_key="무기",
                               transform=lambda v: v if v != "#" else None)

    weapon = db.relationship("ItemList",
                             foreign_keys=[weapon_code],
                             uselist=False,
                             lazy="joined")

    coat_code = CustomColumn(db.String(32),
                             db.ForeignKey("item_list.code"),
                             mapper_key="상의",
                             transform=lambda v: v if v != "#" else None)

    coat = db.relationship("ItemList",
                           foreign_keys=[coat_code],
                           uselist=False,
                           lazy="joined")

    pants_code = CustomColumn(db.String(32),
                              db.ForeignKey("item_list.code"),
                              mapper_key="하의",
                              transform=lambda v: v if v != "#" else None)

    pants = db.relationship("ItemList",
                            foreign_keys=[pants_code],
                            uselist=False,
                            lazy="joined")

    shoes_code = CustomColumn(db.String(32),
                              db.ForeignKey("item_list.code"),
                              mapper_key="신발",
                              transform=lambda v: v if v != "#" else None)

    shoes = db.relationship("ItemList",
                            foreign_keys=[shoes_code],
                            uselist=False,
                            lazy="joined")

    gauntlet_code = CustomColumn(db.String(32),
                                 db.ForeignKey("item_list.code"),
                                 mapper_key="장갑",
                                 transform=lambda v: v if v != "#" else None)

    gauntlet = db.relationship("ItemList",
                               foreign_keys=[gauntlet_code],
                               uselist=False,
                               lazy="joined")

    shield_code = CustomColumn(db.String(32),
                               db.ForeignKey("item_list.code"),
                               mapper_key="방패",
                               transform=lambda v: v if v != "#" else None)

    shield = db.relationship("ItemList",
                             foreign_keys=[shield_code],
                             uselist=False,
                             lazy="joined")

    necklace_code = CustomColumn(db.String(32),
                                 db.ForeignKey("item_list.code"),
                                 mapper_key="목걸이",
                                 transform=lambda v: v if v != "#" else None)

    necklace = db.relationship("ItemList",
                               foreign_keys=[necklace_code],
                               uselist=False,
                               lazy="joined")

    earring_code = CustomColumn(db.String(32),
                                db.ForeignKey("item_list.code"),
                                mapper_key="귀걸이",
                                transform=lambda v: v if v != "#" else None)

    earring = db.relationship("ItemList",
                              foreign_keys=[earring_code],
                              uselist=False,
                              lazy="joined")

    ring_1_code = CustomColumn(db.String(32),
                               db.ForeignKey("item_list.code"),
                               mapper_key="반지1",
                               transform=lambda v: v if v != "#" else None)

    ring_1 = db.relationship("ItemList",
                             foreign_keys=[ring_1_code],
                             uselist=False,
                             lazy="joined")

    ring_2_code = CustomColumn(db.String(32),
                               db.ForeignKey("item_list.code"),
                               mapper_key="반지2",
                               transform=lambda v: v if v != "#" else None)

    ring_2 = db.relationship("ItemList",
                             foreign_keys=[ring_2_code],
                             uselist=False,
                             lazy="joined")

    dress_code = CustomColumn(db.String(32),
                              db.ForeignKey("item_list.code"),
                              mapper_key="옷",
                              transform=lambda v: v if v != "#" else None)

    dress = db.relationship("ItemList",
                            foreign_keys=[dress_code],
                            uselist=False,
                            lazy="joined")

    hat_code = CustomColumn(db.String(32),
                            db.ForeignKey("item_list.code"),
                            mapper_key="모자",
                            transform=lambda v: v if v != "#" else None)

    hat = db.relationship("ItemList",
                          foreign_keys=[hat_code],
                          uselist=False,
                          lazy="joined")

    def to_dict(self) -> dict:
        item_columns = [
            self.weapon, self.coat, self.pants, self.shoes, self.gauntlet,
            self.shield, self.necklace, self.earring, self.ring_1, self.ring_2,
            self.dress, self.hat
        ]

        effects = []
        for i in range(1, 13):
            effect_code = getattr(self, f"effect_{i}_code")
            if effect_code:
                effects.append({
                    "code":
                    effect_code.to_dict(),
                    "operator":
                    getattr(self, f"effect_{i}_operator"),
                    "value":
                    getattr(self, f"effect_{i}_value"),
                })

        return {
            "items": [
                item.to_dict(with_item_data=True) for item in item_columns
                if item
            ],
            "effects":
            effects,
        }
示例#29
0
# 0 - 60 = 61 items per box
for i in range(0, 62):
    # Code
    setattr(RandomBox, f"item_{i}_code",
            CustomColumn(
                db.String(32), db.ForeignKey("item_list.code"),
                mapper_key=f"보상{i}",
                transform=lambda v: v if v != "#" else None))

    # Quantity
    setattr(RandomBox, f"item_{i}_quantity",
            CustomColumn(
                    db.Integer, mapper_key=f"보상수량{i}",
                    transform=lambda v: v if v != 0 else None
                ))

    # Chance
    setattr(RandomBox, f"item_{i}_chance",
            CustomColumn(
                db.Float, mapper_key="보상확률0",
                transform=(
                    lambda v: florensia_probability_transform(v) if v != 0
                    else None)))

    # Relationship
    setattr(RandomBox, f"item_{i}",
            db.relationship(
                "ItemList",
                foreign_keys=[getattr(RandomBox, f"item_{i}_code")]))
示例#30
0
class User(db.Model, UserMixin):
    __tablename__ = 'users'
    __searchable__ = ['username']
    __analyzer__ = ChineseAnalyzer()

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(255), unique=True)
    password = db.Column(db.String(255))
    email = db.Column(db.String(255))
    create_time = db.Column(db.String(255))
    online = db.Column(db.Boolean, default=False)
    last_seen_at = db.Column(db.Integer, default=time.time())
    updated_at = db.Column(db.Integer,
                           default=time.time(),
                           onupdate=time.time())

    roles = db.relationship('Role',
                            secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))
    messages = db.relationship('Message', backref='users', lazy='dynamic')

    def __init__(self, **kwargs):
        self.username = kwargs['username']
        self.password = kwargs['password']

    def __repr__(self):
        return "<User '{}'>".format(self.username)

    def check_username_password(self, username, password):
        user = User.query.filter_by(username=username).first()
        if user is None:
            return False
        elif user.password != password:
            return False
        else:
            return True

    def save(self):
        db.session.add(self)
        db.session.commit()

    def delete(self):
        db.session.delete(self)
        db.session.commit()

    @staticmethod
    def roll_back():
        db.session.rollback()

    def is_authenticated(self):
        return True

    def is_active(self):
        return True

    def is_anonymous(self):
        return False

    def get_id(self):
        return unicode(self.id)

    def can(self, permissions):
        if self.roles is None:
            return False
        all_perms = reduce(or_, map(lambda x: x.permissions, self.roles))
        return all_perms & permissions == permissions

    def ping(self):
        """Marks the user as recently seen and online."""
        self.last_seen_at = time.time()
        last_online = self.online
        self.online = True
        return last_online != self.online

    @staticmethod
    def get_username_by_reg(reg):
        sql = '''
            select username
            from users
            where username REGEXP '{}' LIMIT 5
        '''.format(reg)
        ret = db.engine.execute(sql).fetchall()
        return [dict(r)['username'] for r in ret]

    @staticmethod
    def get_username_limit5():
        sql = '''
            select username
            from users
            LIMIT 5
        '''
        ret = db.engine.execute(sql).fetchall()
        return [dict(r)['username'] for r in ret]