class LearnQuestion(db.Model, search.SearchableMixin): __searchable__ = ["page_name", "question", "answer"] id = db.Column(db.Integer, primary_key=True) page_name = db.Column(db.String(constants.LEARNPAGE_MAX_LEN), index=True) question = db.Column(db.Text) answer = db.Column(db.Text) asker_id = db.Column(db.Integer, db.ForeignKey("user.id")) asker = db.relationship("User", foreign_keys=[asker_id]) show_anon = db.Column(db.Boolean) good_question = db.Column(db.Boolean, index=True, default=False) def __init__(self, page_name, question, asker, show_anon): self.page_name = page_name self.question = question self.asker = asker self.show_anon = show_anon def submit_answer(self, answer_text, mark_as_good=False): self.answer = answer_text self.good_question = mark_as_good @property def html_question(self): return markdown.markdown(self.question, extensions=["extra", "codehilite"]) @property def html_answer(self): return markdown.markdown(self.answer, extensions=["extra", "codehilite"]) def __repr__(self): return f"<Question {self.id}>"
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) author_id = db.Column(db.Integer, db.ForeignKey("user.id")) comments = db.relationship("Comment", backref="parent_post", lazy="dynamic") num_comments = db.Column(db.Integer) title = db.Column(db.String(constants.POST_TITLE_MAX_LEN)) body = db.Column(db.Text) posted_at = db.Column(db.DateTime, default=datetime.datetime.utcnow) edited_at = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow) last_activity = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow) show_anon = db.Column(db.Boolean) followers = db.relationship("User", secondary="post_follow", lazy="dynamic") def __init__(self, author, title, body, show_anon): self.author_id = author.id self.title = title self.body = body self.num_comments = 0 self.show_anon = show_anon def edit(self, new_body, new_anon_policy): if self.body == new_body and self.show_anon == new_anon_policy: return self.body = new_body self.show_anon = new_anon_policy self.edited_at = datetime.datetime.now() self.last_activity = datetime.datetime.now() def notify_followers(self, poster): url = flask.url_for("forum.view_post", post_id=self.id) for follower in self.followers: # Don't notify the comment author if follower.id != poster.id: follower.notify(constants.NEW_COMMENT_NOTIF_STR, url) @property def html_body(self): result = utils.safe_html(self.body) return markdown.markdown(result, extensions=["extra", "codehilite"]) @property def was_edited(self): diff = abs(self.posted_at - self.edited_at) return diff.seconds > 0
class SecretResponse(db.Model): id = db.Column(db.Integer, primary_key=True) secret_id = db.Column(db.Integer, db.ForeignKey("secret.id")) person = db.Column(db.String(constants.SECRET_PERSON_NAME_MAX_LEN)) response = db.Column(db.String(constants.SECRET_RESPONSE_MAX_LEN)) def __init__(self, secret, person, response): self.secret = secret self.person = person self.response = response self.secret.actual_responses += 1
class Comment(db.Model): id = db.Column(db.Integer, primary_key=True) post_id = db.Column(db.Integer, db.ForeignKey("post.id")) author_id = db.Column(db.Integer, db.ForeignKey("user.id")) comment_idx = db.Column(db.Integer) body = db.Column(db.Text) posted_at = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow) edited_at = db.Column(db.DateTime, default=datetime.datetime.utcnow) show_anon = db.Column(db.Boolean) def __init__(self, post, author, body, show_anon): self.post_id = post.id # comment_idx helps with redirects after an edit post.num_comments += 1 self.comment_idx = post.num_comments self.author_id = author.id self.body = body self.show_anon = show_anon def edit(self, new_body, new_anon_policy): if self.body == new_body and self.show_anon == new_anon_policy: return self.body = new_body self.show_anon = new_anon_policy self.edited_at = datetime.datetime.utcnow() @property def html_body(self): result = utils.safe_html(self.body) return markdown.markdown(result, extensions=["extra", "codehilite"]) @property def was_edited(self): diff = abs(self.posted_at - self.edited_at) return diff.seconds > 0
class Task(db.Model): id = db.Column(db.String(constants.TASK_ID_LEN), primary_key=True) name = db.Column(db.String(constants.TASK_NAME_MAX_LEN), index=True) description = db.Column(db.String(constants.TASK_DESC_MAX_LEN)) meta = db.Column(db.Text) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) complete = db.Column(db.Boolean, default=False) def get_rq_job(self): try: return rq.job.Job.fetch(self.id, connection=flask.current_app.redis) except (redis.exceptions.RedisError, rq.exceptions.NoSuchJobError): return None def get_progress(self): job = self.get_rq_job() return job.meta.get('progress', 0) if job is not None else 100
class Warning(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) reason = db.Column(db.String(constants.WARNING_MAX_LEN)) timestamp = db.Column(db.DateTime) def __init__(self, user, reason): self.user = user self.reason = reason self.timestamp = datetime.datetime.utcnow() self.send_notification() def send_notification(self): notification = profile_models.Notification( recipient=self.user, message=self.reason, icon=constants.WARNING_ICON, text_class=constants.WARNING_TEXT_CLASS, ) db.session.add(notification) db.session.commit()
class BugReport(db.Model): id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) report_type = db.Column(db.Integer) text_response = db.Column(db.Text) submitted_at = db.Column(db.DateTime, default=datetime.datetime.utcnow) user = db.relationship("User", foreign_keys=[user_id]) def __init__(self, user, report_type, text_response): if report_type not in REPORT_TYPES.keys(): raise ValueError( f"Invalid report type ({report_type}) not in {REPORT_TYPES.keys()}" ) self.user = user self.report_type = report_type self.text_response = text_response @property def report_type_str(self): return REPORT_TYPES[self.report_type]
class Notification(db.Model): id = db.Column(db.Integer, primary_key=True) recipient_id = db.Column(db.Integer, db.ForeignKey("user.id")) message = db.Column(db.String(constants.NOTIFICATION_MAX_LEN)) url_link = db.Column(db.String(constants.NOTIFICATION_URL_LINK_MAX_LEN)) icon = db.Column(db.String(constants.ICON_MAX_LEN)) text_class = db.Column(db.String(constants.TEXT_CLASS_MAX_LEN)) timestamp = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow) def __init__(self, recipient, message, url_link=None, text_class=None, icon=None): self.recipient = recipient self.message = message self.url_link = url_link self.text_class = text_class self.icon = icon self.send() def send(self): if self.recipient.unread_notifications is None: self.recipient.unread_notifications = 0 self.recipient.unread_notifications += 1 db.session.commit()
class PostFollow(db.Model): __tablename__ = "post_follow" id = db.Column(db.Integer, primary_key=True) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) post_id = db.Column(db.Integer, db.ForeignKey("post.id"))
class MihkPlayer(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(constants.MIHK_PLAYER_NAME_MAX_LEN)) game_id = db.Column(db.Integer, db.ForeignKey("mihk_game.id")) role = db.Column(db.Integer)