|
|
|
|
@ -1,102 +1,112 @@
|
|
|
|
|
import os
|
|
|
|
|
import datetime
|
|
|
|
|
from user_manager import AccountType
|
|
|
|
|
from question_generator import MathQuestion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FileHandler:
|
|
|
|
|
def __init__(self, username: str):
|
|
|
|
|
"""
|
|
|
|
|
初始化文件处理器
|
|
|
|
|
:param username: 用户名,用于创建专属文件夹
|
|
|
|
|
"""
|
|
|
|
|
self.username = username
|
|
|
|
|
self.user_dir = f"{username}_questions/" # 用户专属文件夹
|
|
|
|
|
self._create_user_dir()
|
|
|
|
|
|
|
|
|
|
def _create_user_dir(self) -> None:
|
|
|
|
|
"""创建用户专属文件夹(若不存在)"""
|
|
|
|
|
if not os.path.exists(self.user_dir):
|
|
|
|
|
os.makedirs(self.user_dir)
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _get_current_time_str() -> str:
|
|
|
|
|
"""获取当前时间字符串,格式:年-月-日-时-分-秒"""
|
|
|
|
|
return datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
|
|
|
|
|
|
|
|
|
def _read_existing_questions(self) -> list[MathQuestion]:
|
|
|
|
|
"""读取用户文件夹下所有历史题目,用于查重"""
|
|
|
|
|
existing_questions = []
|
|
|
|
|
if not os.path.exists(self.user_dir):
|
|
|
|
|
return existing_questions
|
|
|
|
|
# 遍历文件夹下所有txt文件
|
|
|
|
|
for filename in os.listdir(self.user_dir):
|
|
|
|
|
if not filename.endswith(".txt"):
|
|
|
|
|
continue
|
|
|
|
|
file_path = os.path.join(self.user_dir, filename)
|
|
|
|
|
# 从文件名提取题目类型
|
|
|
|
|
if "小学" in filename:
|
|
|
|
|
question_type = AccountType.PRIMARY_SCHOOL
|
|
|
|
|
elif "初中" in filename:
|
|
|
|
|
question_type = AccountType.MIDDLE_SCHOOL
|
|
|
|
|
elif "高中" in filename:
|
|
|
|
|
question_type = AccountType.HIGH_SCHOOL
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
# 读取文件内容
|
|
|
|
|
try:
|
|
|
|
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
|
|
|
lines = f.readlines()
|
|
|
|
|
for line in lines:
|
|
|
|
|
line = line.strip()
|
|
|
|
|
if not line or not line[0].isdigit():
|
|
|
|
|
continue
|
|
|
|
|
# 提取题目内容(去掉题号,如"1. 2 + 3" → "2 + 3")
|
|
|
|
|
content_start = line.find(". ") + 2
|
|
|
|
|
if content_start > 1:
|
|
|
|
|
content = line[content_start:]
|
|
|
|
|
existing_questions.append(MathQuestion(content, question_type))
|
|
|
|
|
except IOError as e:
|
|
|
|
|
print(f"读取文件 {file_path} 时发生错误: {e}")
|
|
|
|
|
return existing_questions
|
|
|
|
|
|
|
|
|
|
def is_duplicate(self, question: MathQuestion) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
检查题目是否已存在于历史文件中
|
|
|
|
|
:param question: 待检查的题目对象
|
|
|
|
|
:return: 存在返回True,否则返回False
|
|
|
|
|
"""
|
|
|
|
|
existing = self._read_existing_questions()
|
|
|
|
|
return question in existing
|
|
|
|
|
|
|
|
|
|
def save_questions(self, questions: list[MathQuestion]) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
将题目保存到文件
|
|
|
|
|
:param questions: 待保存的题目列表
|
|
|
|
|
:return: 保存成功返回True,失败返回False
|
|
|
|
|
"""
|
|
|
|
|
if not questions:
|
|
|
|
|
return False
|
|
|
|
|
# 确定题目类型(所有题目类型一致)
|
|
|
|
|
question_type = questions[0].type
|
|
|
|
|
if question_type == AccountType.PRIMARY_SCHOOL:
|
|
|
|
|
type_str = "小学"
|
|
|
|
|
elif question_type == AccountType.MIDDLE_SCHOOL:
|
|
|
|
|
type_str = "初中"
|
|
|
|
|
elif question_type == AccountType.HIGH_SCHOOL:
|
|
|
|
|
type_str = "高中"
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
# 生成文件名
|
|
|
|
|
time_str = self._get_current_time_str()
|
|
|
|
|
filename = f"{time_str}_{type_str}.txt"
|
|
|
|
|
file_path = os.path.join(self.user_dir, filename)
|
|
|
|
|
# 写入文件
|
|
|
|
|
try:
|
|
|
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
|
|
|
for idx, question in enumerate(questions, 1):
|
|
|
|
|
f.write(f"{idx}. {question.content}\n\n") # 每题带题号,空行分隔
|
|
|
|
|
return True
|
|
|
|
|
except IOError as e:
|
|
|
|
|
print(f"保存文件 {file_path} 时发生错误: {e}")
|
|
|
|
|
return False
|
|
|
|
|
import os
|
|
|
|
|
import datetime
|
|
|
|
|
from user_manager import AccountType
|
|
|
|
|
from question_generator import MathQuestion
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FileHandler:
|
|
|
|
|
def __init__(self, username: str):
|
|
|
|
|
"""
|
|
|
|
|
初始化文件处理器
|
|
|
|
|
:param username: 用户名,用于创建专属文件夹
|
|
|
|
|
"""
|
|
|
|
|
self.username = username
|
|
|
|
|
self.user_dir = f"{username}_questions/" # 用户专属文件夹
|
|
|
|
|
self._create_user_dir()
|
|
|
|
|
|
|
|
|
|
def _create_user_dir(self) -> None:
|
|
|
|
|
"""创建用户专属文件夹(若不存在)"""
|
|
|
|
|
if not os.path.exists(self.user_dir):
|
|
|
|
|
os.makedirs(self.user_dir)
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def _get_current_time_str() -> str:
|
|
|
|
|
"""获取当前时间字符串,格式:年-月-日-时-分-秒"""
|
|
|
|
|
return datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
|
|
|
|
|
|
|
|
|
|
def _read_existing_questions(self) -> list[MathQuestion]:
|
|
|
|
|
"""读取用户文件夹下所有历史题目,用于查重"""
|
|
|
|
|
existing_questions = []
|
|
|
|
|
if not os.path.exists(self.user_dir):
|
|
|
|
|
return existing_questions
|
|
|
|
|
# 遍历文件夹下所有txt文件
|
|
|
|
|
for filename in os.listdir(self.user_dir):
|
|
|
|
|
if not filename.endswith(".txt"):
|
|
|
|
|
continue
|
|
|
|
|
file_path = os.path.join(self.user_dir, filename)
|
|
|
|
|
# 从文件名提取题目类型
|
|
|
|
|
if "小学" in filename:
|
|
|
|
|
question_type = AccountType.PRIMARY_SCHOOL
|
|
|
|
|
elif "初中" in filename:
|
|
|
|
|
question_type = AccountType.MIDDLE_SCHOOL
|
|
|
|
|
elif "高中" in filename:
|
|
|
|
|
question_type = AccountType.HIGH_SCHOOL
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
# 读取文件内容
|
|
|
|
|
try:
|
|
|
|
|
with open(file_path, "r", encoding="utf-8") as f:
|
|
|
|
|
lines = f.readlines()
|
|
|
|
|
for line in lines:
|
|
|
|
|
line = line.strip()
|
|
|
|
|
if not line or not line[0].isdigit():
|
|
|
|
|
continue
|
|
|
|
|
# 提取题目内容(去掉题号,如"1. 2 + 3" → "2 + 3")
|
|
|
|
|
content_start = line.find(". ") + 2
|
|
|
|
|
if content_start > 1:
|
|
|
|
|
content = line[content_start:]
|
|
|
|
|
existing_questions.append(MathQuestion(content, question_type))
|
|
|
|
|
except IOError as e:
|
|
|
|
|
print(f"读取文件 {file_path} 时发生错误: {e}")
|
|
|
|
|
return existing_questions
|
|
|
|
|
|
|
|
|
|
def is_duplicate(self, question: MathQuestion) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
检查题目是否已存在于历史文件中
|
|
|
|
|
:param question: 待检查的题目对象
|
|
|
|
|
:return: 存在返回True,否则返回False
|
|
|
|
|
"""
|
|
|
|
|
existing = self._read_existing_questions()
|
|
|
|
|
return question in existing
|
|
|
|
|
|
|
|
|
|
def save_questions(self, questions: list[MathQuestion]) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
将题目保存到文件
|
|
|
|
|
:param questions: 待保存的题目列表
|
|
|
|
|
:return: 保存成功返回True,失败返回False
|
|
|
|
|
"""
|
|
|
|
|
if not questions:
|
|
|
|
|
return False
|
|
|
|
|
# 确定题目类型(所有题目类型一致)
|
|
|
|
|
question_type = questions[0].type
|
|
|
|
|
if question_type == AccountType.PRIMARY_SCHOOL:
|
|
|
|
|
type_str = "小学"
|
|
|
|
|
elif question_type == AccountType.MIDDLE_SCHOOL:
|
|
|
|
|
type_str = "初中"
|
|
|
|
|
elif question_type == AccountType.HIGH_SCHOOL:
|
|
|
|
|
type_str = "高中"
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
|
# 生成文件名
|
|
|
|
|
time_str = self._get_current_time_str()
|
|
|
|
|
filename = f"{time_str}_{type_str}.txt"
|
|
|
|
|
file_path = os.path.join(self.user_dir, filename)
|
|
|
|
|
# 写入文件
|
|
|
|
|
try:
|
|
|
|
|
with open(file_path, "w", encoding="utf-8") as f:
|
|
|
|
|
for idx, question in enumerate(questions, 1):
|
|
|
|
|
f.write(f"{idx}. {question.content}\n\n") # 每题带题号,空行分隔
|
|
|
|
|
return True
|
|
|
|
|
except IOError as e:
|
|
|
|
|
print(f"保存文件 {file_path} 时发生错误: {e}")
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
# file_handler.py 中新增方法
|
|
|
|
|
def get_filename_by_type(self, type_str: str) -> str:
|
|
|
|
|
"""
|
|
|
|
|
根据题目类型生成标准文件名(和 save_questions 逻辑一致)
|
|
|
|
|
:param type_str: 题目类型字符串(如"小学")
|
|
|
|
|
:return: 生成的文件名
|
|
|
|
|
"""
|
|
|
|
|
time_str = self._get_current_time_str()
|
|
|
|
|
return f"{time_str}_{type_str}.txt"
|