class TokenCode(db.Model): "A temporary code to get real user token" __tablename__ = "token_code" code = db.Column(db.String(16), primary_key=True) token = db.Column(db.String(32)) created_at = db.Column(db.DateTime, server_default=func.now()) @classmethod def create(cls): code = urlsafe_b64encode(os.urandom(12)).decode("ascii") db.session.add(cls(code=code)) db.session.commit() return code def bind_token(self, token: str): self.token = token db.session.commit() def get_token(self): token = self.token db.session.delete(self) db.session.commit() return token def expired(self, expiry: int) -> bool: return expired_and_handle(self, expiry)
class AccessToken(db.Model): """ Table to store wechat access_token and its expire time for global use The official expire time is 7200s, but it's better to fetch a new one slightly earlier, so we will set it to 7000s """ __tablename__ = "access_token" token = db.Column(db.String(512), primary_key=True) expire_time = db.Column(db.DateTime()) @classmethod def get(cls, token_getter: Callable) -> str: access_token = cls.query.first() now = datetime.now() if access_token is not None: if access_token.expire_time > now: return access_token.token db.session.delete(access_token) json_response = token_getter() if "access_token" not in json_response: raise ValueError("Access token not found in " + json_response) token = json_response["access_token"] expire_time = now + timedelta(seconds=json_response["expires_in"]) db.session.add(cls(token=token, expire_time=expire_time)) db.session.commit() return token
class SFBackBlessing(db.Model): # 和上面基本一致,多了一个send_to,即向谁发送的列 __tablename__ = "SFBackBlessing" backblessing_id = db.Column(db.Integer, primary_key=True) create_time = db.Column(db.DateTime, server_default=func.now()) create_by = db.Column(db.String(32), nullable=False) send_to = db.Column(db.String(32), nullable=False) content = db.Column(db.Unicode(256)) @classmethod def add_backbless(cls, create_by, send_to, content): if not BlessBan.is_name_baned(create_by): bless_record = cls(create_by=create_by, send_to=send_to, content=content) db.session.add(bless_record) db.session.commit() @classmethod def get_backbless_to(cls, person): return cls.query.filter_by(send_to=person).all() @classmethod def get_by_date(cls, date): "将某一天的祝福数据全部提取出来" return cls.query.filter(func.date(cls.create_time) == date).all() @classmethod def remove_backbless(cls, person=None, backblessing_id=None): if backblessing_id is not None: db.session.delete(cls.query.get(backblessing_id)) if person is not None: ban_lst = cls.query.filter_by(create_by=person).all() for ban_record in ban_lst: db.session.delete(cls.query.get(ban_record.backblessing_id)) db.session.commit()
class User(db.Model): __tablename__ = "user" openid = db.Column(db.String(32), primary_key=True) nickname = db.Column(db.String(32)) avatar = db.Column(BYTEA()) def update(self): db.session.merge(self) db.session.commit()
class SFBlessing(db.Model): __tablename__ = "SFBlessing" blessing_id = db.Column(db.Integer, primary_key=True) create_time = db.Column(db.DateTime, server_default=func.now()) create_by = db.Column(db.String(32), nullable=False) content = db.Column(db.Unicode(256)) @classmethod def add_bless(cls, create_by, content): # 将祝福数据保存在数据库中 if not BlessBan.is_name_baned(create_by): bless_record = cls(create_by=create_by, content=content) db.session.add(bless_record) db.session.commit() return bless_record @classmethod def get_by_date(cls, date): "将某一天的祝福数据全部提取出来" return cls.query.filter(func.date(cls.create_time) == date).all() @classmethod def remove_bless(cls, person=None, blessing_id=None): # 删除某一个id或某一个人的祝福 if blessing_id is not None: db.session.delete(cls.query.get(blessing_id)) if person is not None: ban_lst = cls.query.filter_by(create_by=person).all() for ban_record in ban_lst: db.session.delete(cls.query.get(ban_record.blessing_id)) db.session.commit() @classmethod def get_first_bless_id_by(cls, create_by: str) -> Optional[int]: record = cls.query.filter_by(create_by=create_by).first() if record is None: return None return record.blessing_id @classmethod def undo_bless(cls, create_by: str) -> Optional[str]: "删除用户最后一句祝福,返回其文本" record = (cls.query.filter_by(create_by=create_by).order_by( cls.create_time.desc()).first()) if record is None: return None db.session.delete(record) db.session.commit() return record.content @classmethod def get_creator(cls, blessing_id: int) -> Optional[str]: record = cls.query.get(blessing_id) if record is None: return None return record.create_by
class RandomDraw(db.Model): __tablename__ = "RandomDraw" openid = db.Column(db.String(32), primary_key=True) name = db.Column(db.String(16), nullable=False) @classmethod def add_participant(cls, openid: str, name: str) -> bool: if cls.query.get(openid): return False db.session.add(cls(openid=openid, name=name)) db.session.commit() return True
class CommandStatus(db.Model): __tablename__ = "command_status" name = db.Column(db.String(32), primary_key=True) status = db.Column(db.Boolean, nullable=False) @classmethod def set_status(cls, name: str, status: bool) -> None: db.session.merge(cls(name=name, status=status)) db.session.commit() @classmethod def get_all_status(cls) -> Dict[str, bool]: return {c.name: c.status for c in cls.query.all()}
class AutoReply(db.Model): __table_name__ = "auto_reply" keyword = db.Column(db.Unicode(32), primary_key=True) response = db.Column(db.String(2048)) @classmethod def update(cls, keyword, response): db.session.merge(cls(keyword=keyword, response=response)) db.session.commit() @classmethod def remove(cls, keyword): rows = cls.query.filter(cls.keyword == keyword).delete() db.session.commit() return rows
class CJParticipant(db.Model): __tablename__ = "CJParticipant" event = db.Column(db.String(32), default=settings.eveparty.EVENT, primary_key=True) open_id = db.Column(db.String(32), primary_key=True) name = db.Column(db.String(16), nullable=False) stu_id = db.Column(db.String(32), nullable=False) investment = db.Column(db.String(32), nullable=False) @classmethod def add_user(cls, open_id, name, stu_id): db.session.merge( cls( open_id=open_id, name=name, stu_id=stu_id, investment=json.dumps([1] * settings.eveparty.PRIZE_COUNT), ) ) db.session.commit() @classmethod @get_user def user_invest(cls, user, investment): user.investment = json.dumps(investment) db.session.add(user) db.session.commit() @classmethod @get_user def get_user_name(cls, user): return user.name @classmethod def to_cj_json(cls): return { user.name: json.loads(user.investment) for user in cls.query.filter(cls.event == settings.eveparty.EVENT).all() }
class UserToken(db.Model): __tablename__ = "user_token" token = db.Column(db.String(32), primary_key=True) openid = db.Column(db.String(32)) created_at = db.Column(db.DateTime, server_default=func.now()) @classmethod def create(cls, openid: str = None) -> str: """Create a new user token :param openid: openid of the user the token belongs to. None means blank token waiting for auth. defaults to None :type openid: str, optional :return: The created token :rtype: str """ token = urlsafe_b64encode(os.urandom(24)).decode("ascii") db.session.add(cls(token=token, openid=openid)) db.session.commit() return token def expired(self, expiry: int) -> bool: return expired_and_handle(self, expiry)
class BlessBan(db.Model): # 存储禁掉的人的数据 __tablename__ = "BlessBan" bless_id = db.Column(db.String(32), primary_key=True) @classmethod def add_name(cls, bless_id): # 添加 if not cls.is_name_baned(bless_id): db.session.add(cls(bless_id=bless_id)) db.session.commit() @classmethod def remove_name(cls, bless_id): # 移除 if cls.is_name_baned(bless_id): db.session.delete(cls.query.get(bless_id)) db.session.commit() @classmethod def is_name_baned(cls, bless_id): return cls.query.filter(cls.bless_id == bless_id).first() is not None
class Datax10nProbs(db.Model): __tablename__ = "x10nProbs" probid = db.Column(db.String(4), primary_key=True) text = db.Column(db.String(256), nullable=False) img = db.Column(db.String(256), nullable=False) choices = db.Column(db.String(256), nullable=False) answer = db.Column(db.String(1), nullable=False) @classmethod def put_prob(cls, prob: dict) -> None: assert len(prob) == 4, "不合法的题目形式" assert ( isinstance(prob["probid"], str) and isinstance(prob["text"], str) and isinstance(prob["img"], str) and isinstance(prob["answer"], str) ), "题目前三项应为字符串" assert isinstance(prob["choices"], list), "题目选项应为列表" problem = cls.query.get(prob["probid"]) if problem: print(f"覆盖第{prob['probid']}题") problem.text = prob["text"] problem.img = prob["img"] problem.choices = json.dumps([str(x) for x in prob["choices"]]) problem.answer = prob["answer"] else: problem = cls( probid=prob["probid"], text=prob["text"], img=prob["img"], choices=json.dumps([str(x) for x in prob["choices"]]), answer=prob["answer"], ) db.session.add(problem) db.session.commit() @classmethod def get_prob(cls, probid: str) -> dict: assert isinstance(probid, str), "不合法的id输入" prob = cls.query.get(probid) problem = { "text": prob.text, "img": prob.img, "choices": json.loads(prob.choices), } return problem @classmethod def get_ran_probids(cls, number) -> list: assert isinstance(number, int) and number >= 1, "不合法的数字输入" return [ x.probid for x in db.session.query(cls).order_by(func.random()).limit(number) ] @classmethod def get_ans(cls, probid: str) -> list: assert isinstance(probid, str), "不合法的id输入" prob = cls.query.get(probid) return prob.answer @classmethod def del_prob(cls, probid: str) -> None: assert isinstance(probid, str), "不合法的id输入" prob = cls.query.get(probid) db.session.delete(prob) db.session.commit()
class Datax10n(db.Model): __tablename__ = "x10nUser" openid = db.Column(db.String(32), primary_key=True) result = db.Column(db.String(4096)) starttime = db.Column(db.String(64)) prob_ids = db.Column(db.String(512)) name = db.Column(db.String(32)) stu_id = db.Column(db.String(32)) @classmethod def get_info(cls, openid: str) -> dict: student = cls.query.get(openid) if student is None: student = cls(openid=openid) db.session.add(student) db.session.commit() return {"played": False} return { "played": True, "result": None if student.result is None else json.loads(student.result), } @classmethod def startgame(cls, openid: str, starttime: str, prob_ids: list) -> bool: student = cls.query.get(openid) if student is None: return False else: student.starttime = starttime student.prob_ids = json.dumps(prob_ids) db.session.add(student) db.session.commit() return True @classmethod def get_probs(cls, openid: str) -> list: student = cls.query.get(openid) assert student is not None, "用户不存在" prob_ids = json.loads(student.prob_ids) return prob_ids @classmethod def get_starttime(cls, openid: str) -> float: student = cls.query.get(openid) assert student is not None, "用户不存在" start_time = float(student.starttime) return start_time @classmethod def put_name(cls, openid: str, name: str, stu_id: str) -> bool: student = cls.query.get(openid) assert student is not None, "用户不存在" student.name = name student.stu_id = stu_id db.session.add(student) db.session.commit() return True @classmethod def put_info(cls, openid: str, result: dict) -> bool: student = cls.query.get(openid) if student is None or student.result: return False student.result = json.dumps(result) db.session.add(student) db.session.commit() return True @classmethod def del_info(cls, openid: str) -> bool: "For debug only" student = cls.query.get(openid) db.session.delete(student) db.session.commit()