divid_teacher / session_manager.py
Asem75's picture
Update session_manager.py
6ac2c70 verified
Raw
History Blame Contribute Delete
24.5 kB
# session_manager.py
import os
from datetime import datetime
from student_manager import StudentManager
from curriculum_manager import CurriculumManager
from level_test_manager import LevelTestManager
from mastery_manager import MasteryManager
from attention_manager import AttentionManager
from device_identity_manager import DeviceIdentityManager
try:
from general_culture_manager import GeneralCultureManager
except Exception:
GeneralCultureManager = None
try:
from gap_plan_manager import GapPlanManager
except Exception:
GapPlanManager = None
class SessionManager:
def __init__(self):
self.student_manager = StudentManager()
self.curriculum_manager = CurriculumManager()
self.level_test_manager = LevelTestManager()
self.mastery_manager = MasteryManager()
self.attention_manager = AttentionManager()
self.device_manager = DeviceIdentityManager()
self.general_culture_manager = None
if GeneralCultureManager is not None:
try:
self.general_culture_manager = GeneralCultureManager()
except Exception:
self.general_culture_manager = None
self.gap_plan_manager = None
if GapPlanManager is not None:
try:
self.gap_plan_manager = GapPlanManager()
except Exception:
self.gap_plan_manager = None
self.admin_password = os.getenv("ADMIN_PASSWORD", "1234")
def now(self):
return datetime.utcnow().isoformat()
def normalize_identity(self, identity):
try:
return self.student_manager.normalize_identity(identity)
except Exception:
return str(identity or "").strip().lower().replace(" ", "_")
def normalize_text(self, text):
text = str(text or "").strip().lower()
text = text.replace("أ", "ا").replace("إ", "ا").replace("آ", "ا")
text = text.replace("ة", "ه")
text = text.replace("ى", "ي")
text = text.replace("ؤ", "و")
text = text.replace("ئ", "ي")
text = " ".join(text.split())
return text
def normalize_grade(self, grade):
try:
return self.curriculum_manager.normalize_grade(grade)
except Exception:
return str(grade or "").strip()
def get_student(self, identity):
identity = self.normalize_identity(identity)
try:
student = self.student_manager.get_student(identity)
if isinstance(student, dict):
return student
except Exception:
pass
return None
def save_student(self, student):
try:
return self.student_manager.save_student(student)
except Exception:
return False
def normalize_subject_key(self, subject):
text = self.normalize_text(subject)
if "رياض" in text or "math" in text or "ماث" in text:
return "math", "رياضيات"
if "عربي" in text or "arabic" in text:
return "arabic", "لغة عربية"
if "انجليزي" in text or "انكليزي" in text or "english" in text:
return "english", "لغة إنجليزية"
if "فيز" in text or "physics" in text:
return "physics", "فيزياء"
if "كيم" in text or "chemistry" in text:
return "chemistry", "كيمياء"
if "احياء" in text or "حيات" in text or "biology" in text:
return "biology", "أحياء"
if "ارض" in text or "جيولوج" in text or "earth" in text or "geology" in text:
return "earth_science", "علوم الأرض"
if "بيئ" in text or "environment" in text:
return "environmental_science", "علوم بيئية"
if (
"حاسوب" in text
or "كمبيوتر" in text
or "computer" in text
or "ict" in text
or "تكنولوجيا" in text
or "رقمي" in text
or "برمج" in text
):
return "computer", "حاسوب"
if "علوم" in text or "science" in text:
return "science", "علوم"
return text.replace(" ", "_") or "unknown", subject or "غير محدد"
def is_level_test_subject(self, subject):
key, name = self.normalize_subject_key(subject)
level_subjects = {
"math",
"arabic",
"english",
"science",
"computer",
"physics",
"chemistry",
"biology",
"earth_science",
"environmental_science"
}
return key in level_subjects
def decide_subject_route_safe(self, grade, subject):
key, subject_name = self.normalize_subject_key(subject)
if self.is_level_test_subject(subject):
return {
"route": "level_test",
"subject_key": key,
"subject_name": subject_name,
"subject_type": "level_test",
"needs_level_test": True,
"grade": self.normalize_grade(grade),
"message": "هذه مادة من مواد فحص المستوى."
}
return {
"route": "general_culture",
"subject_key": key,
"subject_name": subject_name,
"subject_type": "general_culture",
"needs_level_test": False,
"grade": self.normalize_grade(grade),
"message": "هذه المادة ليست من مواد فحص المستوى."
}
def register_student_safe(self, student):
identity = student.get("identity", "")
try:
result = self.student_manager.register_student(student)
if isinstance(result, dict):
return result
except Exception:
pass
try:
result = self.student_manager.register_student(**student)
if isinstance(result, dict):
return result
except Exception:
pass
try:
self.student_manager.save_student(student)
except Exception:
pass
loaded = self.get_student(identity)
if isinstance(loaded, dict):
return loaded
return student
def build_new_student(
self,
student_name,
email,
grade,
age,
parent_password
):
identity = self.normalize_identity(student_name)
return {
"identity": identity,
"name": str(student_name or "").strip(),
"email": str(email or "").strip(),
"grade": str(grade or "").strip(),
"age": str(age or "").strip(),
"parent_password": str(parent_password or "").strip(),
"created_at": self.now(),
"updated_at": self.now(),
"level_test": {
"completed": False,
"result": None
},
"level_tests": {},
"homework": [],
"flashcards": [],
"quizzes": [],
"reports": [],
"lesson_history": [],
"progress": {},
"skills": {},
"general_culture": {},
"authorized_devices": []
}
def verify_student_login(self, student_name, hardware_fingerprint):
return self.device_manager.verify_name_and_fingerprint(
student_name=student_name,
fingerprint=hardware_fingerprint
)
def complete_new_student_after_verify(
self,
student_name,
email,
grade,
age,
parent_password,
hardware_fingerprint
):
student_name = str(student_name or "").strip()
email = str(email or "").strip()
grade = str(grade or "").strip()
age = str(age or "").strip()
parent_password = str(parent_password or "").strip()
hardware_fingerprint = str(hardware_fingerprint or "").strip()
if not student_name:
return {
"success": False,
"message": "أدخل اسم الطالب.",
"student": None,
"next_step": "missing_name"
}
if not email:
return {
"success": False,
"message": "أدخل البريد الإلكتروني.",
"student": None,
"next_step": "missing_email"
}
if not grade:
return {
"success": False,
"message": "أدخل الصف.",
"student": None,
"next_step": "missing_grade"
}
if not parent_password:
return {
"success": False,
"message": "أدخل كلمة مرور ولي الأمر.",
"student": None,
"next_step": "missing_parent_password"
}
if not hardware_fingerprint:
return {
"success": False,
"message": "اضغط تحقق لأخذ البصمة.",
"student": None,
"next_step": "missing_fingerprint"
}
owner = self.device_manager.find_owner_by_fingerprint(hardware_fingerprint)
if isinstance(owner, dict):
return {
"success": False,
"message": "هذه البصمة مرتبطة بحساب آخر. لا يمكن استخدام جهاز واحد لحسابين.",
"student": owner,
"next_step": "blocked"
}
existing = self.device_manager.find_one_student_by_name(student_name)
if isinstance(existing, dict):
return {
"success": False,
"message": "الاسم موجود سابقًا. استخدم تحقق الجهاز الجديد بالبريد وكلمة مرور ولي الأمر.",
"student": existing,
"next_step": "verify_existing_device"
}
student = self.build_new_student(
student_name=student_name,
email=email,
grade=grade,
age=age,
parent_password=parent_password
)
student = self.register_student_safe(student)
link_result = self.device_manager.link_device_to_student(
identity=student.get("identity", self.normalize_identity(student_name)),
fingerprint=hardware_fingerprint,
label="الجهاز الأساسي"
)
if not link_result.get("success"):
return {
"success": False,
"message": link_result.get("message", "فشل ربط البصمة."),
"student": student,
"next_step": "device_error"
}
student = link_result.get("student", student)
return {
"success": True,
"message": "تم إنشاء حساب الطالب وربط الجهاز. التالي: فحص المستوى.",
"student": student,
"next_step": "level_test"
}
def verify_existing_device(
self,
student_name,
email,
parent_password,
hardware_fingerprint
):
student_name = str(student_name or "").strip()
email = str(email or "").strip()
parent_password = str(parent_password or "").strip()
hardware_fingerprint = str(hardware_fingerprint or "").strip()
if not student_name or not email or not hardware_fingerprint:
return {
"success": False,
"message": "أدخل الاسم والبريد واضغط تحقق لأخذ البصمة.",
"student": None,
"next_step": "missing_data"
}
student = self.device_manager.find_one_student_by_name(student_name)
if not isinstance(student, dict):
return {
"success": False,
"message": "لم يتم العثور على الطالب.",
"student": None,
"next_step": "not_found"
}
saved_email = str(student.get("email", "")).strip().lower()
given_email = email.strip().lower()
if saved_email and saved_email != given_email:
return {
"success": False,
"message": "البريد الإلكتروني غير مطابق لملف الطالب.",
"student": None,
"next_step": "email_mismatch"
}
saved_parent_password = str(student.get("parent_password", "")).strip()
if saved_parent_password:
if str(parent_password) != saved_parent_password:
return {
"success": False,
"message": "كلمة مرور ولي الأمر غير صحيحة.",
"student": None,
"next_step": "parent_password_mismatch"
}
else:
if not parent_password:
return {
"success": False,
"message": "أدخل كلمة مرور ولي الأمر لحفظها وربط الجهاز.",
"student": None,
"next_step": "missing_parent_password"
}
student["parent_password"] = parent_password
self.save_student(student)
owner = self.device_manager.find_owner_by_fingerprint(hardware_fingerprint)
if isinstance(owner, dict):
owner_identity = self.normalize_identity(owner.get("identity", ""))
student_identity = self.normalize_identity(student.get("identity", ""))
if owner_identity != student_identity:
return {
"success": False,
"message": "هذه البصمة مرتبطة بحساب آخر. لا يمكن استخدام جهاز واحد لحسابين.",
"student": owner,
"next_step": "blocked"
}
link_result = self.device_manager.link_device_to_student(
identity=student.get("identity", self.normalize_identity(student_name)),
fingerprint=hardware_fingerprint,
label="جهاز إضافي"
)
if not link_result.get("success"):
return {
"success": False,
"message": link_result.get("message", "فشل ربط الجهاز."),
"student": None,
"next_step": "device_error"
}
student = link_result.get("student", student)
return {
"success": True,
"message": "تم توثيق الجهاز الجديد وربطه بحساب الطالب.",
"student": student,
"next_step": self.decide_next_step(student)
}
def subject_needs_level_test(self, student, subject):
if not isinstance(student, dict):
return False
if not self.is_level_test_subject(subject):
return False
key, subject_name = self.normalize_subject_key(subject)
level_tests = student.get("level_tests", {})
if isinstance(level_tests, dict):
subject_result = level_tests.get(key)
if isinstance(subject_result, dict) and subject_result.get("completed"):
return False
level_test = student.get("level_test", {})
if isinstance(level_test, dict):
result = level_test.get("result", {})
if isinstance(result, dict):
if result.get("subject_key") == key and level_test.get("completed"):
return False
return True
def has_required_mastery_tasks(self, identity):
try:
return self.mastery_manager.has_required_mastery_tasks(identity)
except Exception:
return False
def has_general_culture_tasks(self, identity):
if self.general_culture_manager is None:
return False
try:
return self.general_culture_manager.has_required_culture_tasks(identity)
except Exception:
return False
def has_gap_plan_tasks(self, identity):
if self.gap_plan_manager is None:
return False
try:
tasks = self.gap_plan_manager.get_waiting_tasks(identity)
return len(tasks) > 0
except Exception:
return False
def check_required_tasks(self, identity, subject=""):
identity = self.normalize_identity(identity)
student = self.get_student(identity)
if not isinstance(student, dict):
return {
"allowed": False,
"screen": "identity_required",
"message": "لم يتم العثور على الطالب.",
"tasks": []
}
tasks = []
if subject and self.subject_needs_level_test(student, subject):
tasks.append({
"type": "level_test",
"title": "فحص المستوى",
"message": "يجب إكمال فحص المستوى لهذه المادة أولًا."
})
if self.has_required_mastery_tasks(identity):
tasks.append({
"type": "mastery_badges",
"title": "أوسمة الإتقان",
"message": "يوجد أوسمة إتقان مطلوبة."
})
if self.has_general_culture_tasks(identity):
tasks.append({
"type": "general_culture",
"title": "الثقافة العامة",
"message": "يوجد أسئلة ثقافة عامة مطلوبة."
})
if self.has_gap_plan_tasks(identity):
tasks.append({
"type": "gap_plan",
"title": "الخطة B",
"message": "يوجد مهام من الخطة B."
})
if tasks:
return {
"allowed": False,
"screen": tasks[0]["type"],
"message": tasks[0]["message"],
"tasks": tasks
}
return {
"allowed": True,
"screen": "lesson",
"message": "يمكن دخول الدرس.",
"tasks": []
}
def decide_next_step(self, student, subject="رياضيات"):
if not isinstance(student, dict):
return "identity_required"
if not student.get("grade"):
return "complete_profile"
if self.subject_needs_level_test(student, subject):
return "level_test"
required = self.check_required_tasks(
identity=student.get("identity", ""),
subject=subject
)
if not required.get("allowed"):
return required.get("screen", "tasks")
return "lesson"
def start_student_session(
self,
identity="",
name="",
email="",
grade="",
age="",
hardware_fingerprint="",
device_source="hardware"
):
student_name = name or identity or email
verify = self.verify_student_login(
student_name=student_name,
hardware_fingerprint=hardware_fingerprint
)
if verify.get("status") == "matched":
student = verify.get("student")
return {
"success": True,
"message": "تم الدخول من الاسم والبصمة.",
"screen": "student_dashboard",
"student": student,
"next_step": self.decide_next_step(student)
}
if verify.get("status") == "new_student":
return self.complete_new_student_after_verify(
student_name=student_name,
email=email,
grade=grade,
age=age,
parent_password="",
hardware_fingerprint=hardware_fingerprint
)
return {
"success": False,
"message": verify.get("message", "لم يتم الدخول."),
"screen": verify.get("status", "login_failed"),
"student": verify.get("student")
}
def route_subject(self, identity, subject):
identity = self.normalize_identity(identity)
student = self.get_student(identity)
if not isinstance(student, dict):
return {
"success": False,
"screen": "identity_required",
"message": "لم يتم العثور على الطالب.",
"data": None
}
route = self.decide_subject_route_safe(
grade=student.get("grade", ""),
subject=subject
)
if route.get("route") == "level_test":
return {
"success": True,
"screen": "level_test",
"message": route.get("message", "هذه مادة من مواد فحص المستوى."),
"route": route,
"data": None
}
return {
"success": True,
"screen": "general_culture",
"message": route.get("message", "هذه المادة ليست من مواد فحص المستوى."),
"route": route,
"data": None
}
def create_level_test_for_subject(self, identity, subject):
identity = self.normalize_identity(identity)
student = self.get_student(identity)
if not isinstance(student, dict):
return {
"success": False,
"message": "لم يتم العثور على الطالب.",
"test": None
}
if not self.is_level_test_subject(subject):
return {
"success": False,
"message": "هذه المادة ليست من مواد فحص المستوى.",
"test": None
}
key, subject_name = self.normalize_subject_key(subject)
return self.level_test_manager.create_level_test(
student=student,
subject=subject_name
)
def submit_level_test(self, identity, subject, test_data, answers_text):
return self.level_test_manager.evaluate_level_test(
identity=identity,
subject=subject,
test_data=test_data,
answers_text=answers_text
)
def admin_login(self, password):
if str(password or "") == str(self.admin_password):
return {
"success": True,
"message": "تم دخول الإدارة."
}
return {
"success": False,
"message": "كلمة مرور الإدارة غير صحيحة."
}
def student_status_summary(self, identity):
identity = self.normalize_identity(identity)
student = self.get_student(identity)
if not isinstance(student, dict):
return "لم يتم العثور على الطالب."
devices = student.get("authorized_devices", [])
if not isinstance(devices, list):
devices = []
level_tests = student.get("level_tests", {})
if not isinstance(level_tests, dict):
level_tests = {}
text = f"""
# حالة الطالب
الاسم: {student.get("name", "")}
البريد: {student.get("email", "")}
الصف: {student.get("grade", "")}
العمر: {student.get("age", "")}
## الأجهزة الموثقة
عدد الأجهزة: {len(devices)}
## فحوصات المستوى المحفوظة
"""
if level_tests:
for key, result in level_tests.items():
if isinstance(result, dict):
text += f"""
- {result.get("subject", key)}: {result.get("percentage", 0)}% - {result.get("level", "")}
"""
else:
text += "\nلا توجد فحوصات مستوى محفوظة بعد."
text += f"""
## التوجيه التالي
{self.decide_next_step(student)}
"""
return text.strip()