user.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. from core.db import WordDatabase
  2. from werkzeug.security import generate_password_hash, check_password_hash
  3. import os
  4. from configure import conf
  5. from flask_login import UserMixin, AnonymousUserMixin
  6. import shutil
  7. from typing import Optional, Tuple
  8. import time
  9. class AnonymousUser(AnonymousUserMixin):
  10. ...
  11. class UserWordDataBase(WordDatabase, UserMixin):
  12. def __check(self, key: int, value: str):
  13. if len(self.search("SELECT value FROM User WHERE key=?", key)) == 0:
  14. self.insert(table="User", columns=["key", "value"], values=f"{key}, '{value}'")
  15. def __init__(self, user: str, path: str):
  16. super().__init__(user, path)
  17. self.done(f'''
  18. CREATE TABLE IF NOT EXISTS User (
  19. id INTEGER PRIMARY KEY AUTOINCREMENT, -- 记录ID
  20. key INTEGER UNIQUE NOT NULL,
  21. value TEXT NOT NULL -- 密码hash
  22. )''')
  23. self.__check(1, generate_password_hash('88888888')) # 默认密码
  24. self.__check(2, time.strftime('%Y#%m#%d', time.localtime(time.time()))) # 更新时间
  25. self.__check(3, '0') # right
  26. self.__check(4, '0') # wrong
  27. self.__check(5, '') # 最近列表
  28. self.check_time() # 更新最后登录时间
  29. self.user = user
  30. def get_id(self):
  31. return self.user
  32. def set_value(self, key: int, value):
  33. value = str(value)
  34. self.update(table="User", kw={"value": f"'{value}'"}, where=f"key={key}")
  35. def get_value(self, key: int, default=None) -> Optional[str]:
  36. res = self.search("SELECT value FROM User WHERE key=?", key)
  37. if len(res) == 0:
  38. return default
  39. return res[0][0]
  40. def check_passwd(self, passwd: str) -> bool:
  41. res = self.get_value(1)
  42. if res is None:
  43. return False
  44. return check_password_hash(res, passwd)
  45. def set_passwd(self, passwd: str):
  46. self.set_value(1, generate_password_hash(passwd))
  47. def check_time(self):
  48. """ 更新时间数据, 按日计 """
  49. now_time = time.strftime('%Y#%m#%d', time.localtime(time.time()))
  50. if self.get_value(2) != now_time: # 最后更新日期(精确到日)与当前不同,则重置数据
  51. self.set_value(2, now_time)
  52. self.set_value(3, 0)
  53. self.set_value(4, 0)
  54. self.set_value(5, "")
  55. def rand_word(self):
  56. w = super(UserWordDataBase, self).rand_word()
  57. if w is None:
  58. return None
  59. self.__add_history_word(w.name)
  60. return w
  61. def right_word(self, w: str):
  62. self.check_time()
  63. self.set_value(3, int(self.get_value(3, 0)) + 1)
  64. return super(UserWordDataBase, self).right_word(w)
  65. def wrong_word(self, w: str):
  66. self.check_time()
  67. self.set_value(4, int(self.get_value(4, 0)) + 1)
  68. return super(UserWordDataBase, self).wrong_word(w)
  69. def __add_history_word(self, w):
  70. history = self.get_value(5, "").split(",")
  71. history.append(w)
  72. if len(history) > 10:
  73. history = history[-10:]
  74. self.set_value(5, ",".join(history))
  75. def delete_user(self):
  76. self.delete_self()
  77. def get_box_count(self) -> Tuple[list, list, int, int]:
  78. res = self.search("SELECT COUNT(word), COUNT(DISTINCT word), box FROM Word GROUP BY box")
  79. ret = [0, 0, 0, 0, 0]
  80. ret_distinct = [0, 0, 0, 0, 0]
  81. for i in res:
  82. ret[i[2] - 1] = i[0]
  83. ret_distinct[i[2] - 1] = i[1]
  84. return ret, ret_distinct, sum(ret), sum(ret_distinct)
  85. def get_history_info(self) -> Tuple[int, int, list]:
  86. self.check_time()
  87. right = int(self.get_value(3))
  88. wrong = int(self.get_value(4))
  89. history = self.get_value(5, "")
  90. if len(history) == 0:
  91. history = []
  92. else:
  93. history = self.get_value(5, "").split(",")[::-1]
  94. return right, wrong, history
  95. def reset(self):
  96. self.update(table="Word", kw={"box": "1"}, where="1")
  97. def check_base_db():
  98. if os.path.exists(os.path.join(conf["DB_TEMPLATE"], "base.db")):
  99. return
  100. WordDatabase("base", conf["DB_TEMPLATE"])
  101. def check_template(template: str) -> bool:
  102. check_base_db()
  103. return os.path.exists(os.path.join(conf["DB_TEMPLATE"], f"{template}.db"))
  104. def get_template():
  105. check_base_db()
  106. file_list = os.listdir(conf["DB_TEMPLATE"])
  107. template = []
  108. for i in file_list:
  109. if i.endswith(".db"):
  110. i = i[:-3]
  111. template.append((i, i.replace("_", " ")))
  112. return template
  113. def create_user(template: str, name: str, passwd: str):
  114. check_base_db()
  115. if not os.path.exists(os.path.join(conf["DB_TEMPLATE"], f"{template}.db")):
  116. return 0, None
  117. if os.path.exists(os.path.join(conf["DB_PATH"], f"{name}.db")):
  118. return -1, None
  119. shutil.copy(os.path.join(conf["DB_TEMPLATE"], f"{template}.db"), os.path.join(conf["DB_PATH"], f"{name}.db"))
  120. user = UserWordDataBase(name, conf["DB_PATH"])
  121. if len(passwd) > 0:
  122. user.set_passwd(passwd)
  123. return 1, user
  124. def have_user(name: str):
  125. return os.path.exists(os.path.join(conf["DB_PATH"], f"{name}.db"))
  126. def load_user(name: str, passwd: Optional[str]):
  127. """ 加载一个用户,如果密码为None表示不检查密码"""
  128. if not os.path.exists(os.path.join(conf["DB_PATH"], f"{name}.db")):
  129. return None
  130. user = UserWordDataBase(name, conf["DB_PATH"])
  131. if passwd is None or user.check_passwd(passwd):
  132. return user
  133. return None